简单 DP 模型

news/2025/11/26 19:28:48/文章来源:https://www.cnblogs.com/qwqxwxpwp/p/19274371

luogu link

写于 2023.08.20

01 背包

朴素算法

//01背包模型 
//给出m个物品及其价值,求在空间为T的背包中可以装的最大价值 
#include<bits/stdc++.h>
using namespace std;
int ans[101][1001];//a[i][q]表示空间为q,在1~i个物品中取物品的最大价值 
int w[101],c[101];
int main(){int m,n;scanf("%d %d",&m,&n);for(int i=1;i<=n;i++) scanf("%d %d",&w[i],&c[i]);for(int i=1;i<=n;i++){//枚举每个物品 for(int q=0;q<=m;q++){//枚举剩余空间 if(q<w[i]) ans[i][q]=ans[i-1][q];//不够放物品i了,不放 else ans[i][q]=max(ans[i-1][q],ans[i-1][q-w[i]]+c[i]);//放和不放物品i间取最大值 }}printf("%d",ans[n][m]);//ans[n][m]即为答案 return 0;
}

降维

#include<bits/stdc++.h>
using namespace std;
int ans[1001];
int w[101],c[101];
int main(){int m,n;scanf("%d %d",&m,&n);for(int i=1;i<=n;i++) scanf("%d %d",&w[i],&c[i]);for(int i=1;i<=n;i++){for(int q=m;q>=w[i];q--){//从后往前保证答案正确,注意当当前空间已经放不下(小于w[i])时就不用再考虑了 ans[q]=max(ans[q],ans[q-w[i]]+c[i]);//放和不放物品i间取最大值 }}printf("%d",ans[m]);//ans[m]即为答案 return 0;
}

完全背包

朴素

//完全背包模型 与01背包相比,每一种物品均可以取无限次 
#include<bits/stdc++.h>
using namespace std;
int w[10005],v[10005];
long long f[10001][10001];
int main(){int m,n;scanf("%d %d",&m,&n);for(int i=1;i<=n;i++) scanf("%d %d",&w[i],&v[i]);for(int i=1;i<=n;i++){for(int q=0;q<=m;q++){//这里的i,q含义与上面的01背包相同 /*容易想到用循环枚举每种物品出现的次数,如下 for(int k=0;k*w[i]<=q;k++){//第i种物品取k个 f[i][q]=max(f[i-1][q],f[i-1][j-k*w[i]]+k*v[i]);}但可以发现这个循环可以直接被优化掉 注意到f[i][q-w[i]]为当前情况少取1个的最优解这样问题就又变为了取或不取,与01背包思路相同 */ f[i][q]=max(f[i-1][q],f[i][q-w[i]]+v[i]); }}printf("%lld",f[n][m]);return 0;
}

降维

//完全背包
#include<bits/stdc++.h>
using namespace std;
int w[10005],v[10005];
long long f[10000001];
int main(){int m,n;scanf("%d %d",&m,&n);for(int i=1;i<=n;i++) scanf("%d %d",&w[i],&v[i]);for(int i=1;i<=n;i++){for(int q=w[i];q<=m;q++){f[q]=max(f[q],f[q-w[i]]+v[i]); }}printf("%lld",f[m]);return 0;
}

分组背包

#include<bits/stdc++.h>
using namespace std;
int f[1005];//意义与先前已经给出的模型相同 
bool group[1005];//辅助数组,标记组数 
vector<int> w[1005],v[1005];//w[i],v[i]表示第i组的占用的空间及价值 
int main(){int m,n,temw,temv,c;scanf("%d %d",&m,&n);for(int i=1;i<=n;i++){scanf("%d %d %d",&temw,&temv,&c);w[c].push_back(temw);//为第c组添加数据 v[c].push_back(temv);group[c]=true;//标记 }int n1=0;for(int i=1;i<=n;i++) if(group[i]) n1++;//n1为出现的组数 for(int i=1;i<=n1;i++){//第i组 for(int q=m;q>=0;q--){//背包剩余容量,此处直接给出一维优化,注意由于重量不确定,需要枚举到0 for(int j=0;j<w[i].size();j++){//本组的每一个元素 //取或不取的最大值 if(q>=w[i][j]) f[q]=max(f[q],f[q-w[i][j]]+v[i][j]); }//这样做每一组只会取一个}}printf("%d",f[m]);return 0;
}

LXS (最长 XX 子序列)

//求最长不升/不降/升/降子序列长度模型,此处以最长不升子序列为例 
//注意,本程序并不能求出最长不升/不降/升/降子序列,仅能求出它们的长度 
#include<bits/stdc++.h>
using namespace std;
vector<int> a;//a[i]表示长度为i+1的最长不升/不降子序列的最后一项 
int num[100005];
bool cmp(const int &a,const int &b){return a>b; 
}
int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&num[i]);for(int i=1;i<=n;i++){if(a.empty()||num[i]<=a[a.size()-1]){/*不降:num[i]>=a[a.size()-1]上升:num[i]>a[a.size()-1]下降:num[i]<a[a.size()-1]此处表示当前需要放置的数字可以直接添加至已有序列的末尾,故直接添加 */a.push_back(num[i]);continue;}int k=upper_bound(a.begin(),a.end(),num[i],cmp)-a.begin();/*不降:upper_bound(a.begin(),a.end(),num[i]);上升:lower_bound(a.begin(),a.end(),num[i]);下降:lower_bound(a.begin(),a.end(),num[i],cmp);注意到我们维护的序列必定有序,所以可以使用二分查找找到第一个大于/小于/大于等于/小于等于当前数的位置,并用当前数替换它这是因为当前数小于等于/大于等于/小于/大于找到的数,对后续数字的添加更为有利 */ a[k]=num[i];}printf("%d",a.size());//求解完整个数列后a的长度就是最长不升/不降/升/降子序列的长度return 0;
}

多重背包

朴素

#include<bits/stdc++.h>
using namespace std;
struct node{int v,w,m;
} a[105];
int ans[40005];
int main(){int n,t;scanf("%d %d",&n,&t);for(int i=1;i<=n;i++) scanf("%d %d %d",&a[i].v,&a[i].w,&a[i].m);for(int i=1;i<=n;i++){for(int q=t;q>=0;q--){for(int j=1;j<=a[i].m&&j*a[i].w<=q;j++){ans[q]=max(ans[q],ans[q-j*a[i].w]+j*a[i].v);}}}printf("%d",ans[t]);return 0;
}

二进制优化

//多重背包
#include<bits/stdc++.h>
using namespace std;
struct node{int v,w;void Set(int V,int W){v=V,w=W;}
} a[100005];
int nown;
int ans[40005];
void work(int v,int w,int m){//对输入的v,w,m进行二进制拆分//二进制拆分的原理:如果x=2^0+2^1+...+2^k+p,//则0~x的所有数均可以使用2^0,2^1,...,2^k,p之间的组合(取或不取)表示 int cnt=1;while(m-cnt>0){a[++nown].Set(v*cnt,w*cnt);m-=cnt,cnt<<=1;//cnt的值依次为:2^0,2^1,2^2,... }a[++nown].Set(v*m,w*m);//最后m的值即为最终剩下的数(p) 
}
int main(){int n,t,v,w,m;scanf("%d %d",&n,&t);for(int i=1;i<=n;i++){scanf("%d %d %d",&v,&w,&m);work(v,w,m);//拆包后问题转换为普通的01背包问题 }for(int i=1;i<=nown;i++){for(int q=t;q>=a[i].w;q--){ans[q]=max(ans[q],ans[q-a[i].w]+a[i].v);}}printf("%d",ans[t]);return 0;
}

单调队列

#include<bits/stdc++.h>
using namespace std;
struct FSI{template<typename T>FSI& operator >>(T&res){res=0; T f=1; char ch=getchar();while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch)){res=(res*10)+(ch-48);ch=getchar();}res*=f;return *this;}
} scan;
typedef long long ll;
const int N=105,M=4e4+5;
int v[N],w[N],cnt[N];
ll dp[2][M];
int q[M],head,tail;
int main(){int n,m;scan>>n>>m;for(int i=1;i<=n;i++) scan>>v[i]>>w[i]>>cnt[i];
//	多重背包: f[i][j]=max(f[i-1][j-k*w[i]]+k*v[i]), k<=cnt[i]
//	记 g[x][y]=f[i][y+x*w[i]],h[x][y]=f[i-1][y+x*w[i]].(0<=y<w[i], 事实上背包中很可能并没有 x 个 i 物品, 只是我们为方便 i 物品的转移假定的)
//	即 g[x][y]=max(h[x-k][y]+k*v[i])=max(h[x-k][y]-(x-k)*v[i])+x*v[i], 可以枚举 y 之后单调队列优化.memset(dp[0],0xcf,sizeof(dp[0]));dp[0][0]=0;for(int i=1;i<=n;i++){for(int y=0;y<w[i];y++){head=1,tail=0;q[++tail]=0;#define f(x) (dp[(i-1)&1][(x)*w[i]+y]-1ll*(x)*v[i])for(int x=0;x*w[i]+y<=m;x++){while(head<=tail&&q[head]<x-cnt[i]) head++;while(head<=tail&&f(q[tail])<=f(x)) tail--;q[++tail]=x;dp[i&1][x*w[i]+y]=f(q[head])+1ll*x*v[i];}}}ll res=0;for(int j=0;j<=m;j++) res=max(res,dp[n&1][j]);printf("%lld\n",res);return 0;
}

事实上对多重背包的单调队列优化是基于完全背包的,你会发现如果物品个数足够多,单调队列的队头永远不会弹掉,变为完全背包。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/977572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型(LLM)基本原理

大模型(LLM)基本原理Posted on 2025-11-26 19:25 Java后端的Ai之路 阅读(0) 评论(0) 收藏 举报什么是AI AI的核心目标是让机器能够执行通常需要人类智能的任务,例如语言理解、图像识别、复杂问题解决等。早期阶…

2025年江苏徐州板式家具、模压托盘、桥洞力学板、三聚氰胺饰面板品牌公司综合推荐指南:五大优质厂商深度解析

摘要 2025年下半年,板式家具行业持续创新,环保材料与智能化生产成为主流趋势。本文基于市场调研和用户反馈,整理出五家值得关注的板式家具品牌(排名不分先后),重点推荐江苏同芯木业。以下推荐表单仅供参考,实际…

Check Point R82 Gaia - 面向安全应用的下一代操作系统

Check Point R82 Gaia - 面向安全应用的下一代操作系统Check Point R82 Gaia - 面向安全应用的下一代操作系统 Quantum Security Gateway and Gaia 请访问原文链接:https://sysin.org/blog/check-point-r82/ 查看最新…

2025年下半年江苏网架、钢结构、光伏支架钢管、托辊钢管、汽车传动轴钢管厂家推荐指南:专业选择与权威解析

摘要 随着建筑行业向工业化、绿色化转型,网架钢结构在2025年下半年的江苏市场迎来新一轮发展高峰。本文基于行业调研和用户反馈,整理出一份网架品牌推荐榜单,排名不分先后,旨在为需求方提供参考。文末附有选择指南…

2025年11月压力容器、化工设备、锅炉、换热器、反应釜厂家怎么选:前五推荐指南

摘要 2025年反应釜行业在化工、石油等领域持续发展,技术创新和可靠性成为关键。本文基于第三方视角,提供2025年11月反应釜公司推荐前五榜单,排名仅为参考,不区分先后顺序,旨在帮助用户选择适合的服务商。榜单基于…

2025年下半年候车亭、公交站台、电子站牌、公交站牌、公交候车厅选购指南:十大优质供应商推荐

摘要 随着城市公共交通体系的不断完善,候车亭作为城市家具的重要组成部分,在2025年下半年的市场需求持续增长。本文整理了当前市场上较具实力的十家候车亭供应商信息,排名不分先后,仅供参考。特别提醒:本文提供的…

2025年下半年江苏徐州冷弯成型前冲孔生产线、C型钢自动抱焊机、钢结构码垛机、H钢冲孔液压设备、光伏支架冲孔机厂家选购指南与市场解析

摘要 随着建筑工业化进程加速,2025年下半年H钢冲孔液压设备市场需求持续增长。本文基于行业调研数据,为您推荐五家技术实力雄厚的设备供应商,排名不分先后,仅供参考。特别说明:本文推荐企业均经过严格筛选,但最终…

2025年下半年冷弯成型前冲孔生产线、C型钢自动抱焊机、钢结构码垛机、H钢冲孔液压设备、光伏支架冲孔机优质供应商推荐指南

2025年下半年,冷弯成型前冲孔生产线行业在智能制造和工业自动化推动下持续发展,市场需求增长显著。本文提供一份推荐榜单,基于第三方调研和用户反馈,列出五家值得考虑的公司,排名不分先后,仅供参考。表单内容旨在…

2025年下半年压力容器、化工设备、锅炉、换热器、反应釜厂家综合推荐指南:十大优质供应商深度解析

摘要 随着工业4.0时代的深入推进,2025年下半年换热器行业迎来新一轮技术革新与市场需求增长。换热器作为化工、石油、能源等领域的核心设备,其性能直接影响生产效率和能源利用率。本文基于市场调研和行业数据,整理出…

从“人工寻宝”到“秒级解析”:文档信息抽取技术重塑保险保单处理流程

在人工智能的语境下,传统的OCR(光学字符识别)技术仅仅完成了“看见”文字的第一步,却无法“理解”文字的语义与逻辑。面对海量、非结构化的汽车保险电子保单,真正的挑战在于如何让机器具备人类的认知能力,精准抽…

2025年下半年轴连轴承、水泵轴承、转向轴承、圆锥滚子轴承、汽车水泵轴承厂家综合推荐指南:十大优质供应商盘点

摘要 随着2025年下半年制造业的持续复苏,圆锥滚子轴承作为工业设备的核心零部件,市场需求呈现显著增长态势。本文基于行业调研数据和技术参数分析,整理出十家值得关注的圆锥滚子轴承供应商推荐榜单,排名不分先后,…

Swift相机功能实战:手把手教你实现扫码、拍照、视频录制全流程 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

全息投影仓的AI连接系统的开发代码要怎么写?

开发一个全息投影舱的AI连接系统是一个非常前沿且复杂的工程。它融合了人工智能、计算机图形学、物联网(IoT)和高性能计算等多个领域。直接给你一份完整的、可生产部署的代码是不现实的,因为这涉及到具体的硬件SDK、…

2025年江苏储物柜、卧室套装、衣柜衣橱、厨房橱柜工厂、全屋定制源头厂家推荐榜单:十大专业厂家综合评测

摘要 2025年下半年厨房橱柜行业迎来新一轮发展机遇,随着智能家居和定制化需求的提升,消费者对厨房橱柜工厂的专业性、可靠性和设计能力提出了更高要求。本文基于市场调研和用户反馈,整理出十家值得关注的厨房橱柜工…

EMNLP 2022自然语言处理技术全景概览

本文系统介绍了某机构在EMNLP 2022会议上发表的40余篇论文,涵盖对话系统、信息抽取、查询重写、提示工程等多个自然语言处理前沿领域,展示了最新的技术架构和研究进展。EMNLP 2022自然语言处理技术全景概览 研究领域…

2025年下半年候车亭、公交站台、电子站牌、公交站牌、公交候车厅厂家综合评估与选购指南

摘要 随着城市化进程加速,2025年候车亭行业迎来智能化、环保化发展新趋势。本文基于市场调研数据,为读者提供五家优质候车亭制造企业的参考表单,排名不分先后,重点推荐综合实力突出的企业供用户选择。所有推荐企业…

VUE3基础环境搭建

VUE3基础环境搭建 1. 安装vue.js npm install vue -g安装webpack Webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。它的主要目的是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器…

基于Halcon的相机图像采集系统设计与达成

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …