分组背包学习笔记

模板题:HDU1712

讲解

模型:给定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;
} 
原文地址:https://www.cnblogs.com/violetholmes/p/14561563.html