当前位置: 首页 > news >正文

动态规划 - 背包详解(下)

题目链接:

1269:【例9.13】庆功会

哈喽,大家好,我们继续来讲背包问题。

上期博客:动态规划 - 背包详解(中)

先复习一下前几期博客的内容。

01 背包:

一维:

​
//01背包 
#include<bits/stdc++.h>
using namespace std;
//定义需要的数组和变量 
const int N=25;
int n,m,w[N],v[N],f[1010];int main(){//输入 cin>>m>>n;for(int i=1;i<=n;i++) cin>>w[i]>>v[i]; for(int i=1;i<=n;i++){for(int j=m;j>=w[i];j--){//状态转移方程f[j]=max(f[j],f[j-w[i]]+v[i]);}}//输出最大值 (max) 并结束程序 cout<<f[m];return 0;
}​

二维:

​
#include<bits/stdc++.h>
using namespace std;
//定义 
const long long N=1010;
long long n,m,dp[N][N],w[N],v[N];
// n:物体数量 
// m:背包最大容量
// dp[i][j]:用来存储 在前 i 件物品时,背包容量为 j 时的最大价值 
// w[i]:存储第 i 件物体的质量 
// v[i]:存储第 i 件物体的价值 int main(){//输入 cin>>n>>m;for(int i=1;i<=n;i++) cin>>w[i]>>v[i];for(int i=1;i<=n;i++){//对前 i 件物品的遍历 for(int j=m;j>0;j--){//容量从大到小遍历 //状态转移方程 //在第 i 件物品能放得下时,考虑在放和不放中的最大价值方案 if(j-w[i]>=0) dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//否则在第 i 件物品放不下时,此时不放第 i 件物品(即与前 i-1 件物品的最大价值相吻合) else dp[i][j]=dp[i-1][j];}}//输出并结束程序 cout<<dp[n][m];return 0;
}​

还记得完全背包问题吗?代码如下:

#include<bits/stdc++.h>
using namespace std;
//定义 
const long long N=1010;
long long n,m,dp[N][N],w[N],v[N];
// n:物体数量 
// m:背包最大容量
// dp[i][j]:用来存储 在前 i 件物品时,背包容量为 j 时的最大价值 
// w[i]:存储第 i 件物体的质量 
// v[i]:存储第 i 件物体的价值 int main(){//输入 cin>>n>>m;for(int i=1;i<=n;i++) cin>>w[i]>>v[i];for(int i=1;i<=n;i++){//对前 i 件物品的遍历 for(int j=m;j>0;j--){//容量从大到小遍历 //状态转移方程 //在第 i 件物品能放得下时,考虑在放和不放中的最大价值方案 if(j-w[i]>=0) dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//否则在第 i 件物品放不下时,此时不放第 i 件物品(即与前 i-1 件物品的最大价值相吻合) else dp[i][j]=dp[i-1][j];}}//输出并结束程序 cout<<dp[n][m];return 0;
}

还有分组背包:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1010;
int n,m,t,x,y,z,dp[N];
vector<int>a[N],b[N];
signed main(){cin>>m>>n>>t;for(int i=0;i<n;i++){cin>>x>>y>>z;a[z].push_back(x);b[z].push_back(y);}for(int i=1;i<=t;i++){for(int j=m;j>=0;j--){for(int k=0;k<a[i].size();k++){if(j<a[i][k]){}else{dp[j]=max(dp[j-a[i][k]]+b[i][k],dp[j]);}}}}cout<<dp[m];return 0;
}

于是我们就复习完了。


现在进入正题。

我们今天来讲多重背包。

先看题:

【题目描述】

为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。

【输入】

第一行二个数n(n≤500),m(m≤6000),其中n代表希望购买的奖品的种数,m表示拨款金额。

接下来n行,每行3个数,v、w、s,分别表示第I种奖品的价格、价值(价格与价值是不同的概念)和能购买的最大数量(买0件到s件均可),其中v≤100,w≤1000,s≤10。

【输出】

一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。

【输入样例】

5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1

【输出样例】

1040

看到此题,其实有两种方法(时间复杂度差不多,空间第一种略大):

第一种:转换成 01 背包。

我们可以将输入的每种若干数量的物品拆成一些物品,就像把

80 20 4

拆成

80 20

80 20

80 20

80 20

于是,就可以用 01 背包啦:

#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int n,m,x,nn=1,y,z,w[N],v[N],f[N*4];
int main(){cin>>n>>m;for(int i=1;i<=n;i++){cin>>x>>y>>z;for(int i=1;i<=z;i++){w[nn]=x;v[nn]=y;nn++;}}for(int i=1;i<=nn;i++){for(int j=m;j>=w[i];j--){f[j]=max(f[j],f[j-w[i]]+v[i]);}}cout<<f[m];return 0;
}

第二种:正正宗宗的多重背包

其实也不难,代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=6010;
int n,m,w[N],v[N],s[N],f[N];
signed main(){cin>>n>>m;for(int i=1;i<=n;i++){cin>>w[i]>>v[i]>>s[i];}for(int i=1;i<=n;i++){for(int j=m;j>=w[i];j--){for(int k=1;k<=s[i]&&k*w[i]<=j;k++){f[j]=max(f[j],f[j-k*w[i]]+k*v[i]);}}}cout<<f[m];return 0;
}

注意:价格和价值是不一样的。

然后大家不要像我第一遍看错大小,否则……像下面:

#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int n,m,w[N],v[N],s[N],f[N];
int main(){cin>>n>>m;for(int i=1;i<=n;i++){cin>>w[i]>>v[i]>>s[i];}for(int i=1;i<=n;i++){for(int j=m;j>=w[i];j--){for(int k=1;k<=s[i]&&k*w[i]<=j;k++){f[j]=max(f[j],f[j-k*w[i]]+k*v[i]);}}}cout<<f[m];return 0;
}

于是只有 90 分了。

最后,这题就讲完了,谢谢大家,我们下次再见!

http://www.dtcms.com/a/431815.html

相关文章:

  • 北京小程序定制开发seo技能培训课程
  • 个人网站设计内容和要求企业做网站带来的好处
  • 关于校园图书馆网站建设公司设计图
  • 怎么样用自己电脑做网站企业注册信息查询单
  • 自己怎么做家政网站做百科需要发哪些网站
  • 网站开发需要哪些资料wordpress主题黑糖
  • 丽江市网站建设制作aspnet网站开发实例教程pdf
  • 添加Entity Framework Core
  • 中小企业加盟网站建设精品建站教程
  • 凡科建设网站入门版好不青木三色品牌商城网站开发
  • 波峰焊万用治具的制作及使用
  • 怎样在手机上创建网站班级网站首页怎么做
  • 拖鞋设计网站推荐做室内概念图的网站
  • 公司建一个网站昆明seocn整站优化
  • Claude Sonnet 4.5重磅发布:Claude Sonnet 4.5新特性大全|更新了什么?
  • 想做个卷帘门百度优化网站网站的版面布局
  • 网站开发实战视频教程广州 骏域网站建设 陶瓷
  • 国内开源建站cms网站注销主体注销
  • 网站开发相关书籍资料5台电脑做视频网站服务器
  • AI赋能千行百业:金融、医疗、教育、制造业的落地实践与未来展望
  • 漳州专业做网站国家开发银行学生在线系统
  • python 网站开发 前端wordpress开发平台
  • 怎样在国外网站购买新鲜橙花做纯露建筑网站排行
  • 修改/替换/删除k次求最长相同子序列的问题
  • 最好的免费软件网站建设东莞本地的发布平台
  • display ospf 概念及题目
  • 旅游网站开发需求文档模板下载长沙网销公司
  • 专业做俄语网站建设个人网站怎么制作成图片
  • 增城商城网站建设服务器怎么设置ip做网站
  • Java Web商城后台商品管理模块