多重背包
Posted nonames
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多重背包相关的知识,希望对你有一定的参考价值。
http://acm.hdu.edu.cn/showproblem.php?pid=2844
题意:给你n种硬币和商品价格m,每种硬币给出价值和数量。问1-m价值中有多少种价值可以用这些硬币表示出来。
解法:因题目数据量较大,必须二进制拆分成01背包优化。
最后遍历所以容量,如果价值等于容量则表示该价格可以表示。
//#include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <cstdio> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> #define ME(x , y) memset(x , y , sizeof(x)) #define SF(n) scanf("%d" , &n) #define rep(i , n) for(int i = 0 ; i < n ; i ++) #define INF 0x3f3f3f3f #define mod 1000000007 #define PI acos(-1) using namespace std; typedef long long ll ; int a[109] , b[109] , val[100009]; int dp[100009]; int main() { /*#ifdef ONLINE_JUDGE #else freopen("D:/c++/in.txt", "r", stdin); freopen("D:/c++/out.txt", "w", stdout); #endif*/ int n , v ; while(~scanf("%d%d" , &n , &v) && n+v) { for(int i = 1 ; i <= n ; i++) { scanf("%d" , &a[i]); } for(int i = 1 ; i <= n ; i++) { scanf("%d" , &b[i]); } memset(dp , 0 , sizeof(dp)); int l = 1 ; for(int i = 1 ; i <= n ; i++) { int c = 1; while(b[i] - c > 0) { val[l++] = c * a[i]; b[i] -= c ; c *= 2 ; } val[l++] = b[i] * a[i]; } for(int i = 1 ; i < l ; i++) { for(int j = v ; j >= val[i] ; j--) { dp[j] = max(dp[j] , dp[j-val[i]]+val[i]); } } int ans = 0 ; for(int i = 1 ; i <= v ; i++) { if(dp[i] == i) { ans ++ ; } } cout << ans << endl ; } return 0 ; }
以上是关于多重背包的主要内容,如果未能解决你的问题,请参考以下文章