HDU2844 Coins(多重背包)

多重背包就是每种物品有数量限制时求解最大价值。

如果一种物品数量和重量之积超过背包容量,可视为完全背包;其余情况通过二进制拆分,将几个数量的物品看成一个,转化为01背包求解。

按照这种思路代码是这样的:

 1 #include<cstdio>//多重背包,二进制拆分
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define M 100005
 6 bool dp[M];//dp[j]表示和为j的组合方式是否可行 
 7 int v[105],c[105];//价值,数量
 8 
 9 void multi_knapsack(int n,int m){
10     for(int i=1;i<=n;i++){
11         if(c[i]*v[i]>=m){//转化为完全背包 
12             for(int j=v[i];j<=m;j++)
13                 if(dp[j-v[i]]) dp[j]=1;
14         }
15         else{
16             for(int k=1;c[i]>0;k<<=1){
17                 int x=min(k,c[i]);
18                 for(int j=m;j>=v[i]*x;j--)//转化为01背包 
19                     if(dp[j-v[i]*x]) dp[j]=1;
20                 c[i]-=x;
21             }
22         }
23     }
24 }
25 
26 int main(){
27     int n,m;
28     while(~scanf("%d%d",&n,&m),n+m){
29         for(int i=1;i<=n;i++) scanf("%d",&v[i]);
30         for(int i=1;i<=n;i++) scanf("%d",&c[i]);
31         memset(dp,0,sizeof(dp));
32         dp[0]=1;//初始状态0可达
33         multi_knapsack(n,m);
34         int ans=0;
35         for(int i=1;i<=m;i++)
36             ans+=dp[i];
37         printf("%d\n",ans);
38     }
39     return 0;
40 }

注意到这道题是可行性问题,可以用一个数组used[j]记录拼成价值j是用了多少个第i种物品,实现数量限制约束。

 1 #include<cstdio>//数组优化
 2 #include<cstring>
 3 using namespace std;
 4 #define M 100005
 5 int v[105],c[105],used[M];
 6 bool dp[M];
 7 
 8 int main(){
 9     int n,m,ans;
10     while(~scanf("%d%d",&n,&m),n&&m){
11         for(int i=1;i<=n;i++) scanf("%d",&v[i]);
12         for(int i=1;i<=n;i++) scanf("%d",&c[i]);
13         memset(dp,0,sizeof(dp));
14         ans=0,dp[0]=1;
15         for(int i=1;i<=n;i++){
16             memset(used,0,sizeof(used));
17             for(int j=v[i];j<=m;j++)
18                 if(!dp[j]&&dp[j-v[i]]&&used[j-v[i]]<c[i]){
19                     dp[j]=1;
20                     used[j]=used[j-v[i]]+1;
21                     ans++;
22                 }
23         }
24         printf("%d\n",ans);
25     }
26     return 0;
27 }

 

posted @ 2022-06-18 14:43  YHXo  阅读(31)  评论(0编辑  收藏  举报