01背包模板
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=1000;
int v[N+50],w[N+50];
int f[N+50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>v[i]>>w[i];
}
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>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=1000;
int v[N+50],w[N+50];
int f[N+50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>v[i]>>w[i];
}
for(int i=1;i<=n;i++)
{
for(int j=v[i];j<=m;j++)
{
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[m];
return 0;
}
多重背包模板 I
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=1000;
int v[N+50],w[N+50],s[N+50];
int f[N+50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>v[i]>>w[i]>>s[i];
}
for(int i=1;i<=n;i++)
{
for(int j=m;j>=v[i];j--)
{
for(int k=0;k<=s[i]&&k*v[i]<=j;k++)
{
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
}
}
}
cout<<f[m];
return 0;
}
多重背包模板 II
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=100000;
int vv[N+50],ww[N+50];
int f[N+50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
int num=1;
for(int i=1;i<=n;i++)
{
int v,w,s;
cin>>v>>w>>s;
for(int j=1;j<=s;j<<=1)
{
vv[num]=j*v;
ww[num]=j*w;
num++;
s-=j;
}
if(s)
{
vv[num]=s*v;
ww[num]=s*w;
num++;
}
}
for(int i=1;i<num;i++)
{
for(int j=m;j>=vv[i];j--)
{
f[j]=max(f[j],f[j-vv[i]]+ww[i]);
}
}
cout<<f[m];
return 0;
}
多重背包模板 III
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=20000;
int f[N+50],g[N+50],q[N+50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
int num=1;
for(int i=1;i<=n;i++)
{
memcpy(g,f,sizeof(f));
int v,w,s;
cin>>v>>w>>s;
for(int j=0;j<v;j++)
{
int h=0,t=-1;
for(int k=j;k<=m;k+=v)
{
if(h<=t&&q[h]<k-s*v)
{
h++;
}
if(h<=t)
{
f[k]=max(g[k],g[q[h]]+(k-q[h])/v*w);
}
while(h<=t&&g[k]>=g[q[t]]+(k-q[t])/v*w)
{
t--;
}
q[++t]=k;
}
}
}
cout<<f[m];
return 0;
}
混合背包模板
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=1000;
int f[N+50],g[N+50],q[N+50];
int n,m;
void ZeroOnePack(int v,int w)
{
for(int j=m;j>=v;j--)
{
f[j]=max(f[j],f[j-v]+w);
}
}
void CompletePack(int v,int w)
{
for(int j=v;j<=m;j++)
{
f[j]=max(f[j],f[j-v]+w);
}
}
void MultiplePack(int v,int w,int s)
{
memcpy(g,f,sizeof(f));
for(int j=0;j<v;j++)
{
int h=0,t=-1;
for(int k=j;k<=m;k+=v)
{
if(h<=t&&q[h]<k-s*v)
{
h++;
}
if(h<=t)
{
f[k]=max(g[k],g[q[h]]+(k-q[h])/v*w);
}
while(h<=t&&g[k]>=g[q[t]]+(k-q[t])/v*w)
{
t--;
}
q[++t]=k;
}
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int v,w,s;
cin>>v>>w>>s;
if(s==-1)
{
ZeroOnePack(v,w);
}
else if(s==0)
{
CompletePack(v,w);
}
else
{
MultiplePack(v,w,s);
}
}
cout<<f[m];
return 0;
}
二维费用的背包模板
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=1000;
int f[N+50][N+50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,V,M;
cin>>n>>V>>M;
for(int i=1;i<=n;i++)
{
int v,m,w;
cin>>v>>m>>w;
for(int j=V;j>=v;j--)
{
for(int k=M;k>=m;k--)
{
f[j][k]=max(f[j][k],f[j-v][k-m]+w);
}
}
}
cout<<f[V][M];
return 0;
}
分组背包模板
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
const int N=100;
int v[N+50],w[N+50];
int f[N+50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,V;
cin>>n>>V;
for(int i=1;i<=n;i++)
{
int s;
cin>>s;
for(int j=1;j<=s;j++)
{
cin>>v[j]>>w[j];
}
for(int j=V;j>=1;j--)
{
for(int k=0;k<=s;k++)
{
if(j>=v[k])
{
f[j]=max(f[j],f[j-v[k]]+w[k]);
}
}
}
}
cout<<f[V];
return 0;
}
有依赖的背包模板
#include<iostream>
#include<cstring>
using namespace std;
const int N=110;
int n,V,p,root;
int v[N],w[N];
int h[N],to[N],ne[N],tot; //邻接表
int f[N][N];
void add(int a,int b){
to[++tot]=b;ne[tot]=h[a];h[a]=tot;
}
void dfs(int u){
for(int i=v[u];i<=V;i++) f[u][i]=w[u];
for(int i=h[u]; i; i=ne[i]){ //子节点
int s=to[i];
dfs(s);
for(int j=V;j>=v[u];j--) //体积
for(int k=0;k<=j-v[u];k++)//决策
f[u][j]=max(f[u][j],f[u][j-k]+f[s][k]);
}
}
int main(){
cin>>n>>V; //物品个数,背包容量
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i]>>p; //体积,价值,依赖的物品编号
if(p==-1) root=i;
else add(p,i);
}
dfs(root);
cout<<f[root][V];
}
背包问题求方案数模板
// 不超背包容量的方案数
#include<iostream>
#include<cstring>
using namespace std;
const int N=1010, mod=1e9+7;
int f[N],c[N];
// f[i]表示背包容量为i时最优选法的总价值
// c[i]表示背包容量为i时最优选法的方案数
int main(){
int n, m, v, w;
scanf("%d%d", &n, &m);
for(int i=0;i<=m;i++) c[i]=1;
for(int i=1; i<=n; i++){ //枚举物品
scanf("%d%d",&v,&w);
for(int j=m; j>=v; j--){ //枚举体积
if(f[j-v]+w>f[j]){ //装新物品总价值更大
f[j]=f[j-v]+w;
c[j]=c[j-v];
}
else if(f[j-v]+w==f[j]) //装新物品总价值相等
c[j]=(c[j]+c[j-v])%mod;
}
}
printf("%d\n",c[m]);
}
背包问题求具体方案模板
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1010;
int v[N],w[N];
int f[N][N],p[N][N];
int main(){
int n,m; cin>>n>>m;
for(int i=1; i<=n; i++) cin>>v[i]>>w[i];
for(int i=n; i>=1; i--) //逆序取物
for(int j=0; j<=m; j++){ //枚举体积
f[i][j]=f[i+1][j];
p[i][j]=j; //记录路径列
if(j>=v[i])
f[i][j]=max(f[i][j],f[i+1][j-v[i]]+w[i]);
if(j>=v[i] && f[i][j]==f[i+1][j-v[i]]+w[i])
p[i][j]=j-v[i];
}
int j=m;
for(int i=1; i<=n; i++)
if(p[i][j]<j){
printf("%d ",i);
j=p[i][j];
}
}