题解 | #多重背包#

多重背包

https://ac.nowcoder.com/acm/problem/235950

背包问题:

起初并未想到二进制优化,因为这一题数据范围不大,因此可以用O(n3)的解法,提交代码如下:

 include <bits/stdc++.h>
 using namespace std;
 int n,t;
 int x,w,v;
 int dp[101][1001];
 int main ()
 {
   
   cin>>n>>t;
   
   for(int i=1;i<=n;i++){
     
     cin>>x>>w>>v;
     
   for(int j=1;j<=t;j++){
     
     for(int k=0;k<=x;k++){
       
       if(j>=k*w){
         
         dp[i][j]=max(dp[i][j],dp[i-1][j-k*w]+k*v);
         
         }
       
       }
     
     }
     
   }
   
   cout<<dp[n][t]<<endl;
   
   return 0;
   
 }

后来考虑到如果数据过大,比如是2000或者3000等,上述做法就会超时,因此,我们能想到用二进制优化代码,二进制优化就是本来有n种物品,然后共有count个物品,将它们的相应的个数对应的价值和重量分别存到一个数组中去,最后再写一个二重循环来求解dp数组,dp[i]表示到达i的重量时物品所能达到的最大价值,相应的代码如下:

 include <bits/stdc++.h>
 using namespace std;
 int n,t;
 int x,w,v;
 int v1[1001],w1[1001];
 int dp[1001];
 int main ()
 {
   
   cin>>n>>t;
   
   int count=0;
   
   for(int i=0;i<n;i++){
     
     int k=1;
     
     cin>>x>>w>>v;
     
     while(k<=x){
       
       count++;
       
       w1[count]=k*w;
       
       v1[count]=k*v;
       
       x-=k;
       
       k*=2;
       
       }
     
     if(x){
       
       count++;
       
       w1[count]=x*w;
       
       v1[count]=x*v;
       
     }
     
   }
   
   for(int i=1;i<=count;i++){
     
     for(int j=t;j>=w1[i];j--){
       
       dp[j]=max(dp[j],dp[j-w1[i]]+v1[i]);
       
     }
     
   }
   
   cout<<dp[t]<<endl;
   
   return 0;
   
 }
全部评论
666
1 回复 分享
发布于 2023-07-29 12:18 安徽

相关推荐

真烦好烦真烦:豆包润色了自己没看看吗,再说了,都说豆包是愚蠢且勤快的大学生,ds才是聪明的研究生,怎么敢让豆包写论文的
点赞 评论 收藏
分享
待现的未见之事:起码第一句要把自己的优势说出来吧。比如什么xx本27届学生,随时到岗....
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务