杭电oj 2191 多重背包问题
1 8 2 2 100 4 4 100 2
400
解题思路:这个题是个多重背包的问题,不同于完全背包(每个物品有无限件),与01背包也不大相同(此题的物品件数固定),但类似于01背包,所以可以将此题转换成01背包问题来求解。利用三重循环,第二重循环是第i个物品的件数,有多少件第三重循环就执行多少次,完全转换成01背包来写。下面给出两种转换方法,虽然代码不大一样,但原理一样。
具体代码一: #include <stdio.h> #include <string.h> #define max(a,b) a>b?a:b struct Node { int p,h,c; }s[105]; int dp[105]; int main() { int C; scanf("%d",&C); while(C--) { int n,m,i,j; scanf("%d%d",&n,&m); for(i=0;i<m;i++) scanf("%d%d%d",&s[i].p,&s[i].h,&s[i].c); memset(dp,0,sizeof(dp)); for(i=0;i<m;i++) while(s[i].c--)//每一件都寻求依次最优解 for(j=n;j>=s[i].p;j--) dp[j]=max(dp[j],dp[j-s[i].p]+s[i].h); printf("%d\n",dp[n]); } return 0; }
具体代码二: #include <stdio.h> #include <string.h> #define max(a,b) a>b?a:b struct Node { int p,h,c; }s[105]; int dp[105]; int main() { int C; scanf("%d",&C); while(C--) { int n,m,i,j,k; scanf("%d%d",&n,&m); for(i=0;i<m;i++) scanf("%d%d%d",&s[i].p,&s[i].h,&s[i].c); memset(dp,0,sizeof(dp)); for(i=0;i<m;i++) for(j=n;j>=s[i].p;j--) for(k=1;k*s[i].p<=j&&k<=s[i].c;k++)//类似于上面的while dp[j]=max(dp[j],dp[j-k*s[i].p]+k*s[i].h); printf("%d\n",dp[n]); } return 0; }