当前位置:网站首页>动态规划:背包问题模板代码汇总
动态规划:背包问题模板代码汇总
2022-07-28 18:35:00 【2,4(1H,3H)-PD are mine】
说明:根据acwing算法提高课和算法基础课整理,代码根据y总的稍加修改。
1.0-1背包问题
问题模型描述:
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
模板题:2. 01背包问题 - AcWing题库
代码(空间优化版):
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N];
int main()
{
int n,m;
cin>>n>>m; //数量和总体积
for(int i=0;i<n;++i){
int v,w; //v:体积;w:价值
cin>>v>>w;
for(int j=m;j>=v;--j) f[j]=max(f[j],f[j-v]+w);
}
cout<<f[m];
return 0;
}2.完全背包问题
问题模型描述:0-1背包问题的基础上,每一个物品可以无限选用。
代码(优化到O(n^2),空间一维):
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N];
int main()
{
int n,m;
cin>>n>>m; //数量和总体积
for(int i=0;i<n;++i){
int v,w; //v:体积;w:价值
cin>>v>>w;
for(int j=v;j<=m;++j) f[j]=max(f[j],f[j-v]+w);
}
cout<<f[m];
return 0;
}3.分组背包问题
问题模型描述:
有 N 组物品和一个容量是 V 的背包。每组物品有若干个,同一组内的物品最多只能选一个。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int f[N],v[N][N],w[N][N],s[N];
int main()
{
int n,m;
cin>>n>>m; //数量和总体积
for(int i=1;i<=n;++i){
cin>>s[i]; //第i类的个数
for(int j=1;j<=s[i];++j) cin>>v[i][j]>>w[i][j];
}
for(int i=1;i<=n;++i)
for(int j=m;j>=0;--j)
for(int k=1;k<=s[i];++k)
if(v[i][k]<=j) f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);
cout<<f[m];
return 0;
}4.最长公共上升子序列问题
这个不算背包模型,算是区间dp,朴素做法复杂度是O(n^3),这里贴上O(n^2)复杂度的代码。
问题模型描述:两个数列 A 和 B,如果它们都包含一段位置不一定连续的数,且数值是严格递增的,那么称这一段数是两个数列的公共上升子序列,而所有的公共上升子序列中最长的就是最长公共上升子序列。
代码(O(n^2)):
#include<bits/stdc++.h>
using namespace std;
const int N=3010;
int n,a[N],b[N],f[N][N];
int main()
{
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n;++i) cin>>b[i];
for(int i=1;i<=n;++i){
int maxv=1;
for(int j=1;j<=n;++j){
f[i][j]=f[i-1][j];
if(a[i]==b[j]) f[i][j]=max(f[i][j],maxv);
if(b[j]<a[i]) maxv=max(maxv,f[i][j]+1);
}
}
int res=0;
for(int i=1;i<=n;++i) res=max(res,f[n][i]);
cout<<res;
return 0;
}5.背包问题求方案数
问题模型描述:0-1背包问题的基础上,最优选法的方案数。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1010,mod=1e9+7;
int f[N],g[N];
int main()
{
int n,m;
cin>>n>>m;
g[0]=1;
for(int i=0;i<n;++i){
int v,w;
cin>>v>>w;
for(int j=m;j>=v;--j){
int mav=max(f[j],f[j-v]+w),cnt=0;
if(mav==f[j]) cnt+=g[j];
if(mav==f[j-v]+w) cnt+=g[j-v];
cnt%=mod;
g[j]=cnt;
f[j]=mav;
}
}
int res=0,ans=0;
for(int i=0;i<m;++i) res=max(res,f[i]);
for(int i=0;i<m;++i) if(res==f[i]) ans=(ans+g[i])%mod;
cout<<ans;
return 0;
}6.有依赖的背包问题。
问题模型描述:有 N 个物品和一个容量是 V 的背包。物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。
状态表示:f[u][m]:以u为根节点的子树,在代价不超过m时产生的最大价值。
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int h[N],ne[N],e[N],idx,v[N],w[N],f[N][N];
int n,m;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{
for(int i=h[u];~i;i=ne[i]){
int son=e[i];
dfs(son);
for(int j=m-v[u];j>=0;--j)
for(int k=0;k<=j;++k)
f[u][j]=max(f[u][j],f[u][j-k]+f[son][k]);
}
for(int i=m;i>=v[u];--i) f[u][i]=f[u][i-v[u]]+w[u];
for(int i=0;i<v[u];++i) f[u][i]=0;
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof(h));
int r;
for(int i=1;i<=n;++i){
int p;
cin>>v[i]>>w[i]>>p;
if(p==-1) r=i;
else add(p,i);
}
dfs(r);
cout<<f[r][m];
return 0;
}7.多重背包问题
问题模型描述:0-1背包问题的基础上,第i个物品最多选择si件。
代码(二进制优化版):
#include<bits/stdc++.h>
using namespace std;
const int M=2010,N=25000;
int v[N],w[N],f[M];
int main()
{
int n,m;
cin>>n>>m;
int cnt=0;
for(int i=1;i<=n;++i){
int a,b,s;
cin>>a>>b>>s;
int k=1;
while(k<=s){
++cnt;
v[cnt]=a*k,w[cnt]=b*k;
s-=k;
k<<=1;
}
if(s>0){
++cnt;
v[cnt]=a*s,w[cnt]=b*s;
}
}
n=cnt;
for(int i=1;i<=n;++i)
for(int j=m;j>=v[i];--j)
f[j]=max(f[j],f[j-v[i]]+w[i]);
cout<<f[m];
return 0;
}滑动窗口优化版:
#include<bits/stdc++.h>
using namespace std;
const int N=20010;
int f[N],g[N],q[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;++i){
int v,w,s;
cin>>v>>w>>s;
memcpy(g,f,sizeof(f)); //存上一层状态
for(int j=0;j<v;++j){
int hh=0,tt=-1;
for(int k=j;k<=m;k+=v){
if(hh<=tt&&q[hh]<k-s*v) hh++;
if(hh<=tt) f[k]=max(f[k],g[q[hh]]+(k-q[hh])/v*w);
while(hh<=tt&&g[q[tt]]-(q[tt]-j)/v*w<=g[k]-(k-j)/v*w) tt--;
q[++tt]=k;
}
}
}
cout<<f[m];
return 0;
}
8.组合背包问题
问题模型描述:有 N 种物品和一个容量是 V 的背包。
物品一共有三类:
- 第一类物品只能用1次(01背包);
- 第二类物品可以用无限次(完全背包);
- 第三类物品最多只能用 si 次(多重背包);
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
int f[N];
int main()
{
cin>>n>>m;
for(int i=0;i<n;++i){
int v,w,s;
cin>>v>>w>>s;
if(s==0) //完全背包
for(int j=v;j<=m;++j) f[j]=max(f[j],f[j-v]+w);
else{
if(s==-1) s=1; //01背包相当于个数为1的多重背包
for(int k=1;k<=s;k*=2){
for(int j=m;j>=k*v;--j) f[j]=max(f[j],f[j-k*v]+k*w);
s-=k;
}
if(s) for(int j=m;j>=s*v;--j) f[j]=max(f[j],f[j-s*v]+s*w);
}
}
cout<<f[m];
return 0;
}
边栏推荐
- Usage Summary of thymeleaf
- 83. (cesium home) how the cesium example works
- Yum package management
- js飞入js特效弹窗登录框
- 太空游戏第12课: 盾牌
- Pop up modal box
- Networkx common operations summary (for personal use)
- 根据openGauss/MogDB的lwtid查看线程堆栈。
- [experiment sharing] CCIE BGP reflector experiment
- Solutions to the environment created by Anaconda that cannot be displayed in pycharm
猜你喜欢

Raspberry pie 4B parsing PWM

Residual network RESNET source code analysis - pytoch version

Solve the problem that the nocturnal simulator cannot access the Internet after setting an agent

Raspberrypico analytic PWM

数据挖掘(数据预处理篇)--笔记

Configure Windows Server + install MySQL database on the server + Remote Access database

Pop up modal box

Quick sort template

一文让你搞懂什么是TypeScript

Leetcode-297 serialization and deserialization of binary tree
随机推荐
太空射击第14课: 玩家生命
js图表散点图例子
The product power is greatly improved, and the new Ford Explorer is released
Install keras, tensorflow, and add the virtual environment to the Jupiter notebook
LeetCode_位运算_中等_260.只出现一次的数字 III
[detailed use of doccano data annotation]
产品经理访谈 | 第五代验证码的创新与背景
3D激光SLAM:LeGO-LOAM论文解读---简介部分
[fasttext -- Summary notes]
Introduction to seven kinds of polling (practice link attached)
Simple example of C language 1
Does any elder brother know how to solve the huge flinksql log
C language - data storage
Vivado designs PC and ram
Classes and objects (medium)
Character device drive structure
太空射击第16课: 道具(Part 2)
Raspberry pie uses the command line to configure WiFi connections
Raspberry pie 4B ffmpeg RTMP streaming
超大模型工程化实践打磨,百度智能云发布云原生AI 2.0方案