可以看看作者的dp讲解,有助于理解
作者太菜了,所以只有这几个,咱们慢慢来,会一步一步更新的
01背包
void 01bag()
{
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];
}
/*
f[j] 表示重量为j的答案
每个物品有选和不选两种选择:
1.选 f[j]=f[j-重量]+价值
2.不选 f[j]不变
f[m]即为重量为m的最佳答案,即我们需要的数
*/
完全背包
void allbag()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>v>>w;
for(int j=v;j<=m;j++)
f[j]=max(f[j],f[j-v]+w);
}
cout<<f[m];
return 0;
}
/*
与01背包相差不大,倒过来即可
相当于一种物品,有W/重量个,再把这W个物品分解成01背包
*/
二维背包(有体积有重量)
const int MAXN=1005;
int f[MAXN][MAXN],V,N,M,tj,zl,jz;
/*TDK,是二维背包(Two dimensional knapsack)的缩写*/
void TDK
{
cin>>N>>V>>M;
for(int i=1;i<=N;i++)
{
cin>>tj>>zl>>jz;
for(int j=V;j>=tj;j--)
{
for(int k=M;k>=zl;k--)
f[j][k]=max(f[j][k],f[j-tj][k-zl]+jz);
}
}
cout<<f[V][M];
}
/*
这题近似于01背包
普通的01背包:f[i][j]=max(f[i-1][j],f[i-1][j-重量]+价值)
现在的01背包:f[i][j][k]=max(f[i-1][j],f[i-1][j-体积][k-重量]+价值)
01背包优化:f[j][k]=max(f[j][k],f[j-体积][k-重量])
答案是f[总体积][总重量]
*/
多重背包I
int m,n,v,w,s,f[1005],g,v2[1005],w2[1005];
//MB是Multiple backpack(多重背包的缩写)
void MBI()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>v>>w>>s;
for(int j=1;j<=s;j++)
{
g++;
v2[g]=v;
w2[g]=w;
}
}
n=g;
for(int i=1;i<=n;i++)
for(int j=m;j>=v2[i];j--)
f[j]=max(f[j-v2[i]]+w2[i],f[j]);
cout<<f[m];
}
/*
状态转移方程:f[j]=max(f[j],f[j-v]+w,f[j-2*v]+2*w......f[j-s*v]+s*w)
答案:f[m]
*/
多重背包II
作者太菜了,占时不会II,推荐一篇别人的题解
一个天梯分段位大师的大佬写的,含金量很高,连我这种懒癌晚期(懒癌晚期,即经常拖更)的都看懂了
混合背包
int a[10005],b[10005];
int t=0,n,m,f[10005]={0},w,v,s;
/*MultiplePack=多重背包=MP,II为等级*/
void MPII()
{
cin>>n>>m;
while(n--)
{
cin>>v>>w>>s;
if(s==-1) s=1;
else if(s==0) s=m/v;
/*s=-1可以看做 数量为1 的多重背包
s=0可以看做 数量为m/v(再多也装不下) 的多重背包
s>0就是单纯的数量为s的多重背包
此题关键就是理解这一点
*/
//多重背包II模板
for(int i=1;;i*=2)
{
if(s<i) break;
s-=i;
a[++t]=v*i;
b[t]=w*i;
}
//转换二进制
if(s>0) a[++t]=v*s,b[t]=w*s;//还有剩余另起一个
}
for(int i=1;i<=t;i++)
for(int j=m;j>=a[i];j--)
f[j]=max(f[j-a[i]]+b[i],f[j]);//01背包模板
cout<<f[m]<<endl;
return 0;
}
分组背包
/*Packet backpack=PB=分组背包*/
int v[105][105],w[105][105],n,m,l[105],f[105];
void PB()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>l[i];
for(int j=1;j<=l[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<=l[i];k++)
if(j>=v[i][k]) f[j]=max(f[j-v[i][k]]+w[i][k],f[j]);
}
}
cout<<f[m];
return 0;
}
/*
n为组数,m为总重量,l[i]为第i组物品个数,v[i][j]表示第i组第j个物品的体积,w[i][j]表示第i组第j个物品的价值
j为当前重量,i为组的编号
状态转移方程:f[j]=max(f[j](不选),f[j-v[i][1]+w[i][1](选第一个),f[j-v[i][2]]+w[i][2](选第二个)......f[j-v[i][l[i]]+w[i][l[i]](选第l[i]个));
*/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
好的,马上复制