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

背包习题

文章目录

  • 背包习题
    • [278. 数字组合 - (01背包,求方案数)](https://www.acwing.com/problem/content/280/)
      • 思路
      • 代码
    • [279. 自然数拆分 - (完全背包,求方案数)](https://www.acwing.com/problem/content/281/)
      • 思路
      • 代码
    • [P1060 (01 背包)](https://www.luogu.com.cn/problem/P1060)
      • 思路
      • 代码
    • [P1757 ( 分组背包 )](https://www.luogu.com.cn/problem/P1757)
      • 思路
      • 代码
    • [280. 陪审团 - (二维费用,求具体方案)](https://www.acwing.com/problem/content/282/)
      • 思路
      • 代码
    • [281. 硬币 - 多重背包](https://www.acwing.com/problem/content/283/)
      • 思路
      • 代码

背包习题

建议结合背包九讲(灵魂版)-CSDN博客这篇博客进行学习

278. 数字组合 - (01背包,求方案数)

给出 n n n个数字,组合= m m m,求几种组合方式

思路

这个题对应背包九讲(灵魂版)-CSDN博客中的背包问题求方案数知识。

既然和为 m m m,我们将把体积看作 m m m,结合01背包,这里最优价值,其实就是m.也就是每1体积,价值为1。

所以我们将数组 f f f,赋值f[0]=1,其余=0.为了保证结果是由0递推得出。

因为01背包不同物品的单位体积价值不同,所以需要int t=max(dp[j],dp[j-v[i]]+w[i])进行比较得出更优。

而这里选择哪个效果都是一样的,只要能组合成 m m m.所以这个题不需要比较。直接用 f [ j ] + = f [ j − v ] f[j]+=f[j-v] f[j]+=f[jv]

也就是更新累加体积为 j j j时选择该物品的方案数

代码

#include<bits/stdc++.h>
#define fir(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,m,a[105],f[10500];
int main()
{cin>>n>>m;f[0]=1;for(int i=1;i<=n;i++)cin>>a[i];fir(i,1,n){for(int j=m;j>=a[i];j--)f[j]+=f[j-a[i]];}cout<<f[m]<<'\n';
}

279. 自然数拆分 - (完全背包,求方案数)

将数字拆分为至少两个正整数相加,求方案数,对结果取模

思路

题目标签是完全背包,再结合求方案数问题,根据上一题代码略加修改即可。

我们需要将** j j j循环变成正序**,即每个数字可以重复考虑,这是完全和01区别。

i i i循环怎么写?
它表示的是选择的数字,我们选择数字的范围是**[1,m-1]**。

记得开long long,取模

代码

#include<bits/stdc++.h>
#define fir(i,a,b) for(int i=a;i<=b;i++)
#define int long long
using namespace std;
int n,m,f[10500];
signed main()
{cin>>m;f[0]=1;fir(i,1,m-1){for(int j=i;j<=m;j++){f[j]+=f[j-i];f[j]%=2147483648; }}cout<<f[m]%2147483648<<'\n';
}

P1060 (01 背包)

给定总钱数 n n n,物品总数 m m m.再 n n n范围内,使得 价值 v ∗ 重要程度 w 价值v*重要程度w 价值v重要程度w最大。

思路

显而易见的01背包

代码

int dp[30050],v[30],p[30];
signed main()
{IOSint n,m;cin>>n>>m;fir(i,1,m){cin>>v[i]>>p[i];for(int j=n;j>=v[i];j--){dp[j]=max(dp[j],dp[j-v[i]]+v[i]*p[i]);}}cout<<dp[n]<<'\n';return 0;
}

P1757 ( 分组背包 )

思路

和模板题区别就是,需要开个容器去分类存放物品。之后三个循环,进行状态转移。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define fir(i,a,b) for(int i=a;i<=b;i++)
#define PII pair<int,int> 
#define fi first
#define se second
const int N=1e3+10;
map<int,vector<PII> > v;
int dp[N];
signed main()
{IOSint n,m;cin>>m>>n;fir(i,1,n){   int a,b,c;cin>>a>>b>>c;v[c].push_back({a,b});}for(auto it:v){  for(int j=m;j>=1;j--){   for(auto ww:it.se){    int v= ww.fi,w=ww.se; if(j>=v)dp[j]=max(dp[j],dp[j-v]+w);}}}cout<<dp[m]<<'\n';
}

280. 陪审团 - (二维费用,求具体方案)

思路

既要满足m个,还要差值最小,再找到和最大,且求具体方案

为了解决这些问题,

  • 我们需要初始化为负无穷。为了保证所得结果一定是差值最小的,而不是由其他更大差值状态转移所得。
  • 差值可正可负,因为是总差值,所以中间阶段不能简单的用绝对值。所以整体+400.用 400 + ( d [ i ] − p [ i ] ) = 400 − p [ i ] + d [ i ] 400+(d[i]-p[i])=400-p[i]+d[i] 400+(d[i]p[i])=400p[i]+d[i]表示差值,此时范围是【0,800】
  • 因为求具体方案,不能降维,三个循环 i , 遍历每一个评分; j , 更新选择不同数量 1 , m ; k , 遍历所有可能差值 i,遍历每一个评分; j,更新选择不同数量1,m; k,遍历所有可能差值 i,遍历每一个评分;j,更新选择不同数量1m;k,遍历所有可能差值,不断更新dp.
  • d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示考虑前 i i i个评分,选取 j j j个,差值为 k k k时的最大和。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=205;
int dp[N][25][810],p[N],d[N];
int main()
{   int n,m,T=1;while( cin>>n>>m){if(n==0&&m==0) break;memset(dp,128,sizeof(dp));//初始化无穷小dp[0][0][400]=0;//初始化为for(int i=1;i<=n;i++){cin>>p[i]>>d[i];for(int j=0;j<=m;j++){for(int k=0;k<=800;k++){int t=k-p[i]+d[i];dp[i][j][k]=dp[i-1][j][k];if(j-1<0||t<0||t>800) continue;//该状态不可选取dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][t]+p[i]+d[i]);}} }int k=0;//找到最小差值while(dp[n][m][400-k]<0&&dp[n][m][400+k]<0) k++;if(dp[n][m][k+400]>dp[n][m][400-k]) k=400+k;else k=400-k;//查询判断入选的人int c=0,i=n,j=m,a[N];while(j){if(dp[i][j][k]==dp[i-1][j][k])  {i--;continue;}a[c++]=i;   k-=(p[i]-d[i]);j--,i--;}   int pp=0,dd=0;for(int i=c-1;i>=0;i--){pp+=p[a[i]];dd+=d[a[i]];}printf("Jury #%d\n",T);printf("Best jury has value %d for prosecution and value %d for defence:\n",pp,dd);for(int i=c-1;i>=0;i--)//题目要求升序!!!cout<<" "<<a[i];  cout<<"\n\n";//两个换行符!!!T++;}
}

281. 硬币 - 多重背包

给定 N种硬币,其中第 i 种硬币的面值为 Ai,共有 Ci 个。

从中选出若干个硬币,把面值相加,若结果为 S,则称“面值 S能被拼成”。

求 1∼M之间能被拼成的面值有多少个。

思路

i i i 遍历每一个物品,对于每一个物品,用一个数组used存放,该硬币使用了多少次。

对于 j 没组合, j − a [ i ] j-a[i] ja[i]可组合,且使用次数足够。说明可以组合成功,更新一下。

代码

#include<bits/stdc++.h>
using namespace std;
int c[120],a[120],f[100050],used[110000];//f是bool类型,used存放不同面值下该硬币使用次数
int main()
{int n,m;while(cin>>n>>m,n&&m){for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++) cin>>c[i];memset(f,0,sizeof(f));//初始化f[0]=1;     //面值为0,初始化为1  for(int i=1;i<=n;i++){    memset(used,0,sizeof used);//对于不同硬币,进行初始化for(int j=a[i];j<=m;j++){if(!f[j]&&f[j-a[i]]&&used[j-a[i]]<c[i])//j没组合成,j-a[i]已组合,硬币i使用次数足够{f[j]=1;//标记可组合used[j]=used[j-a[i]]+1;}}}int ans=0;for(int i=1;i<=m;i++)//计算有多少可组合if(f[i]) ans++;cout<<ans<<'\n';}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • CSS 中高度 100%和高度 100vh 有什么区别
  • 第二证券:静态市盈率与动态市盈率有什么区别?
  • 区块链(币圈)常用网址大全
  • STM32F411 标准库硬件SPI (硬件NSS/CS)驱动st7735--1.8寸TFT显示屏
  • 搭建自己的金融数据源和量化分析平台(八):解析PDF财报中的资产负债表
  • 深入浅出神经网络-学习小结
  • 大数据技术之Flume 企业开发案例——负载均衡和故障转移(6)
  • 行为模式6.备忘录模式------文本的撤销和保存
  • 专业的固定资产管理系统平台|一分钟带你了解它的特色功能,引领企业智能化转型!
  • Spring Boot项目中结合MyBatis详细使用
  • 【前缀和】--- 初阶题目赏析
  • 趣味算法------多重背包问题
  • 阿里云OSS迁移至华为云OBS,Java整合华为云OMS实现文件的自动批量迁移功能
  • [数据集][目标检测]管道漏水泄漏破损检测数据集VOC+YOLO格式2614张4类
  • 设计一个算法,用最少的时间在顺序表中找到x,若找到,与后继交换,找不到插入到顺序表中,任保持有序。
  • const let
  • CSS 三角实现
  • Flex布局到底解决了什么问题
  • httpie使用详解
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • sublime配置文件
  • Vue 动态创建 component
  • yii2权限控制rbac之rule详细讲解
  • 从输入URL到页面加载发生了什么
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 缓存与缓冲
  • 基于 Babel 的 npm 包最小化设置
  • 聊聊directory traversal attack
  • 日剧·日综资源集合(建议收藏)
  • 王永庆:技术创新改变教育未来
  • 【干货分享】dos命令大全
  • Nginx实现动静分离
  • 大数据全解:定义、价值及挑战
  • ​io --- 处理流的核心工具​
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​queue --- 一个同步的队列类​
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (2)空速传感器
  • (70min)字节暑假实习二面(已挂)
  • (a /b)*c的值
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (PADS学习)第二章:原理图绘制 第一部分
  • (Python第六天)文件处理
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二)Kafka离线安装 - Zookeeper下载及安装
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十三)Flask之特殊装饰器详解
  • (译) 函数式 JS #1:简介
  • .md即markdown文件的基本常用编写语法
  • .net 7 上传文件踩坑
  • .net core 使用js,.net core 使用javascript,在.net core项目中怎么使用javascript
  • .net framework 4.8 开发windows系统服务