一般的なナップザック問題の概要と最適化されたコード(DP)
1.01バックパック
注最適化:第二層はサイクルである逆の順序で、理由は、ここで検索を読者に説明しない。
次のコアコードに。
for(int i=1;i<=n;i++)///n物品数,m背包容量
for(int j=m;j>=w[i];j--)//w[i]物品i的重量,v[i]物品i的价值
f[j]=max(f[j],f[j-w[i]]+v[i]);
2.フルバックパック(回数01記事無制限のバックパックの各)
01の異なるユニークな最適化されたポイントとバックパックである:第二層は、ループである配列、その理由は、ここで検索を読者に説明しない。
次のコアコードに。
for(int i=1;i<=n;i++)
for(int j=w[i];j<=m;j++)
f[j]=max(f[j],f[j-w[i]]+v[i]);
3.複数のバックパック(01リュックアップグレード版、アイテムの数、各有限)
01マルチバックパックバックパックの拡張である各記事の数がマルチパックであるように、バックパック01を見ることができる。
以下のコアコードに。
for(int i=1;i<=n;i++)
for(int j=1;j<=p[i];j++)
for(int k=m;k>=w[i];k--)
f[k]=max(f[k],f[k-w[i]]+v[i]);
4.バックパックパケット(それぞれが一つだけの物品01リュック変異体から選択されます)
トリプルサイクルを最適化する場合、ループは層配列を有することに留意されたいです。
コアコードをここに。
vector<int>p[N];//二维数组p[i][j]表示第i组的第j个物品的序号数,方便查找w[i],v[i]
int w[N],v[N],f[N],pos;//pos表示物品在那个组。
for(int i=1;i<=n;i++){
cin>>w[i]>>v[i]>>pos;
p[pos].push_back(i);
}
for(int i=1;i<=t;i++)
for(int j=v;j>=0;j--)
for(int k=0;k<p[i].size();k++)
{
int x=p[i][k];//第i组第k个物品的序号数
if(w[x]<=j) f[j]=max(f[j],f[j-w[x]]+v[x]);
}
5.ミックスバックパック(完全な複数のバックパックやリュックサック本体)
複数のバックパックと裁判官がうまくている場合、コードで合併を完了することです。
コアコードをここに。
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i]>>p[i];
for(int i=1;i<=n;i++){
if(!p[i]){//完全背包
for(int j=w[i];j<=m;j++)
f[j]=max(f[j],f[j-w[i]]+v[i]);
}else{ //多重背包与01背包.
for(int j=1;j<=p[i];j++)
for(int k=m;k>=w[i];k--)
f[k]=max(f[k],f[k-w[i]]+v[i]);
}
(多次元に基づいて、01バックパックの最適化)6.ダブル条件01リュック
for(int i=1;i<=n;i++)
for(int j=w1;j>=w1[i];j--)
for(int k=w2;k>=w2[i];k--)
dp[j][k]=max(dp[j][k],dp[j-w1[i]][k-w2[i]]+v[i]);
要約:01バックパック、複数のバックパック、バックパックグルーピング逆の順序を。
バックパック完全順次、バックパック三重ループパケット(多層物品は、各グループを横断する、層の順序である:グループの数-容量-各グループ内の項目の数)、複数の混合リュックサックバックパック、完全なバックパックの混合物(決意IF)
--------------- --------------------------------継続するには------------------