分组背包学习笔记
讲解
模型:给定n件物品,其中第i种物品体积为v[i],价值为w[i]。将这些物品划分为k组,每组物品最多选1件。求总体积不超过m的前提下,物品最大总价值。
思路:既然每组只可选一件,可以将其视作一件物品,但决策时需循环组内物品取最优。
伪代码:
for ( 1 ≤ i ≤ k ) //组别
for ( m ≥ j ≥ 0 ) //体积(倒序)
for ( k:第i组中的物品 ) 01背包的转移;
物品只得在第3层循环,否则同组物品会被多次选取(与体积倒序循环原因相同)。
AC代码(hdu1712)
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int a[N][N],dp[N];
int main()
{
int n,m;
while(1)
{
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&m);
if(!n && !m) break;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=m;j>=0;j--)
for(int k=1;k<=j;k++) dp[j]=max(dp[j],dp[j-k]+a[i][k]);
printf("%d\n",dp[m]);
}
return 0;
}