【POJ】1742 coins 【背包问题】
2011-09-27 22:35
363 查看
1 思路:
f[j](1<=j<=m)数组用来表示j是不是可以达到,现假设可达。 b[j](1<=j<=m)数组用在第二层循环中,表示当价值为j时物品i已经用了几个。记录此值的原因:例如已经知道了j=10可以取到,现还有物品A价值2,数目2。不能通过此信息知道12、14可达,因为j=10可达的时候有可能已经把A这两个物品都用过了,所以需要记录此值,当b[10]=2时表明A已经用过2次了,不能再用了,故12、14都不能可达。 现假设有一物品价值a[i],数量为c[i],若b[j-a[i]]<c[i]表示i还没有用完,还可以再用。
f[j-a[i]] == 1表明j-a[i]可以达到,且f[j]==0表示f[j]以前还没有取到过。j>=a[i]条件是必须的,否则不可能取这第i件物品。若上面条件同时满足,则说明j可以达到,设置f[j]=1, 此时i用的数目因为j的使用而多了一个,所以b[j]=b[j-a[i]]+1。
2 代码
#include <cstdio> #include <iostream> #include <cstring> using namespace std; const int maxn = 110; const int maxm = 100010; int a[maxn], c[maxn], b[maxm]; bool f[maxm]; int n, m, ans; int main(int argc, char *argv[]) { int i, j; while (scanf("%d%d",&n,&m) && n && m){ for(i=1; i<=n; i++) cin>>a[i]; for(i=1; i<=n; i++) cin>>c[i]; ans = 0; memset(f, 0, sizeof(f)); f[0] = 1; for(i=1; i<=n; i++){ memset(b, 0, sizeof(b)); for(j=1; j<=m; j++) if(j>=a[i] && !f[j] && f[j-a[i]] && b[j-a[i]]+1<=c[i]){ f[j]=1; b[j] = b[j-a[i]]+1; ans ++; } } cout<<ans<<endl; } return 0; }
footnote
感谢ccy!
Author: visaya fan gmail.com]<visayafan[AT]gmail.com>
Date: 2011-08-24 01:47:48
HTML generated by org-mode 6.33x in emacs 23
相关文章推荐
- poj 1742 coins 背包问题
- poj 1742 Coins (动态规划,背包问题)
- POJ 1742 && HDU 2844 Coins(多重背包问题)
- poj 1742 Coins【多重背包可行性问题】
- (复习)poj 1742 coins 多重背包可达性问题
- POJ 1742 Coins(多重背包可行性问题)
- POJ 1742 Coins 混合三种背包问题
- poj-1742 COINS(多重背包问题)
- poj 1742 Coins(多重背包可行性问题)
- 动态规划(背包问题):POJ 1742 Coins
- poj 1742 Coins (多重背包可行性问题)
- POJ 1742-Coins [dp 多重背包问题] 《挑战程序设计竞赛》2.3
- poj 1742 coins_多重背包
- (优化的有限背包) poj 1742 Coins(转载)
- POJ 1742 Coins 多重背包入门题
- POJ-1742:Coins(多重背包二进制求法)
- poj_2392_Space Elevator & poj_1742_Coins 一种多重背包
- poj1742(背包问题)
- poj1742 Coins 动态规划 多重背包 待补完
- poj 1742 Coins 背包dp