HDU 1085 多重背包转化为0-1背包问题
2014-12-24 10:52
225 查看
题目大意:
给定一堆1,2,5价值的硬币,给定三个数表示3种价值硬币的数量,任意取,找到一个最小的数无法取到
总价值为M = v[i]*w[i](0<=i<3)
那么在最坏情况下M个数都能取到 , M+1必然取不到
所以给M+1个背包,往里面塞东西,最后由前往后检测,找到第一个无法取满的背包的体积
这道题目里,每一种物品的v*w必然小于M+1,所以不出现完全背包的情况,全部采用多重背包转化为0-1背包解决问题即可
给定一堆1,2,5价值的硬币,给定三个数表示3种价值硬币的数量,任意取,找到一个最小的数无法取到
总价值为M = v[i]*w[i](0<=i<3)
那么在最坏情况下M个数都能取到 , M+1必然取不到
所以给M+1个背包,往里面塞东西,最后由前往后检测,找到第一个无法取满的背包的体积
这道题目里,每一种物品的v*w必然小于M+1,所以不出现完全背包的情况,全部采用多重背包转化为0-1背包解决问题即可
#include <cstdio> #include <cstring> using namespace std; #define max(a,b) a>b?a:b const int N = 10000; int dp , a[3] , M; int v[3] = {1 , 2 , 5}; void zeroPack(int w , int v) { for(int i = M ; i >= w ; i--) dp[i] = max(dp[i-w]+v , dp[i]); } void multiPack(int n , int w , int v) { int t = 1; while(n > t){ zeroPack(t*w , t*v); n -= t; t <<= 1; } if(n > 0) zeroPack(n*w , n*v); } int main() { while(1){ M = 0; for(int i = 0 ; i<3 ; i++){ scanf("%d" , a+i); M += a[i] * v[i]; } if(M == 0) break; //这里加一表示可能你加起来的总值都能够取到,但是多加个一,那么必然会有一个最大值取不到 M += 1; memset(dp , 0 ,sizeof(dp)); for(int i = 0 ; i<3 ; i++){ multiPack(a[i] , v[i] , v[i]); } int k = 0; while(dp[k] == k) k++; printf("%d\n" , k); } return 0; }
相关文章推荐
- hdu 2844 多重背包的转化问题 以及这个dp状态的确定
- HDU 1114 完全背包问题的转化
- 01背包及完全背包问题(51Nod - 1085,HDU 1114 Piggy-Bank)
- hdu 2955(DP背包问题)
- http://acm.hdu.edu.cn/showproblem.php?pid=2844&&背包问题
- hdu 1059 Dividing--DP-多重背包问题
- hdu 1421 搬寝室--类背包问题
- HDU 1284 钱币兑换问题 母函数 or 完全背包
- hdu 1059 Dividing(二进制转化优化) 分组背包
- hdu 2159 背包问题
- http://acm.hdu.edu.cn/showproblem.php?pid=3591&&背包问题
- hdu 2159 FATE(二位费用的多重背包问题)
- 一个0-1背包问题(hdu 1203)
- hdu 1284 钱币兑换问题(完全背包 变形---求方案总数)
- hdu 1085 Holding Bin-Laden Captive! (多重背包变形)
- hdu 2602一个典型的背包问题
- hdu1171_多重背包转化为01背包
- HDU 2955(0-1背包问题)
- hdu 1864 01背包问题
- HDU-3339 最短路+背包问题