1 /* 2 将01背包,完全背包,和多重完全背包问题结合起来,那么就是混合三种背的问题 3 根据三种背包的思想,那么可以得到 4 混合三种背包的问题可以这样子求解 5 for(int i=1; i<=N; ++i) 6 if(第i件物品是01背包) 7 zeroOnePack(c[i],w[i]); 8 else if(第i件物品是完全背包) 9 completePack(c[i],w[i]); 10 else if(第i件物品是多重完全背包) 11 multiplePack(c[i],w[i],n[i]); 12 13 这样能得到最优解的原因是,因为前一层已经是得到最优解了, 14 当前层求解最优解的时候,我们考虑要使用三种背包中的哪一种方法 15 而不用考虑前一层是怎么得到最优解的 16 */ 17 #include <stdio.h> 18 #include <string.h> 19 20 /* 21 有n件物品和一个容量为v的背包,第i种物品最多有n[i]件可用, 22 每件费用是c[i],价值是w[i],求解将哪些物品放入背包 23 使费用总和不超过背包容量且价值总和最大 24 25 for(i=1; i<=n; ++i) 26 for(j=0; j<=v; ++j) 27 for(k=0; k*c[i]<=j; ++k) 28 dp[i][j] = max(dp[i][j],dp[i-1][j-k*c[i]]+k*w[i]); 29 时间复杂度为O(V*∑n[i]); 30 另一种思想是二进制优化,时间复杂度为O(V*∑log(n[i])); 31 详见图片 32 */ 33 #include <stdio.h> 34 #include <string.h> 35 int cash; 36 int n[11],dk[11]; 37 int dp[1000000]; 38 inline int max(const int &a, const int &b) 39 { 40 return a < b ? b : a; 41 } 42 void CompletePack(int cost) 43 { 44 for(int i=cost; i<=cash; ++i) 45 dp[i] = max(dp[i],dp[i-cost]+cost); 46 } 47 void ZeroOnePack(int cost) 48 { 49 for(int i=cash; i>=cost; --i) 50 dp[i] = max(dp[i],dp[i-cost]+cost); 51 } 52 void MultiplePack(int cnt, int cost) 53 { 54 if(cnt*cost >=cash)//如果第i种物品的费用总和超过背包容量,那么就是完全背包问题 55 CompletePack(cost); 56 else 57 { 58 int k = 1;//二进制拆分 59 while(k<cnt)//判断剩下的数字能不能够拆分为k 60 { 61 ZeroOnePack(cost*k); 62 cnt -=k; 63 k<<=1; 64 } 65 ZeroOnePack(cnt*cost); 66 } 67 } 68 int main() 69 { 70 //输入的处理以及函数的调用 71 return 0; 72 }
时间: 2024-10-13 19:30:05