思路:多重背包模板,分解成多个01背包,可以说就是01背包问题,时间复杂度O(V*∑n[i])
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int dp[1010],w[1010],v[1010]; int main() { int n,m,t; scanf("%d",&t); while(t--) { int k=0,w1,v1,sum; scanf("%d %d",&n,&m); for(int i=0;i<m;i++) { scanf("%d %d %d",&v1,&w1,&sum); while(sum--)//把多重背包分解成sum个01背包; { v[k]=v1; w[k]=w1; k++; } } memset(dp,0,sizeof(dp)); for(int i=0;i<k;i++) { for(int j=n;j>=v[i];j--) { dp[j]=max(dp[j],dp[j-v[i]]+w[i]); } } printf("%d\n",dp[n]); } return 0; }推荐:
利用快速幂思想转化成01背包,当数据比较大的时候比较优,算法时间复杂度O(V*∑log n[i]);
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; int dp[1010], w[1010], v[1010]; int main() { int n, m, t; scanf("%d", &t); while(t--) { int k=0, w1, v1, sum; scanf("%d %d", &n, &m); for(int i = 0; i < m; i++) { scanf("%d %d %d", &v1, &w1, &sum); int t = 1; while(sum >= t) { v[k] = t * v1; w[k++] = t * w1; sum -= t; t <<= 1; } if(sum) { v[k] = sum * v1; w[k++] = sum * w1; } } memset(dp, 0, sizeof(dp)); for(int i = 0; i < k; i++){ for(int j = n; j >= v[i]; j--) { dp[j] = max(dp[j], dp[j - v[i]] + w[i]); } } printf("%d\n", dp[n]); } return 0; }