LUOGU P1757 通天之分组背包

蒟蒻的第一篇博客,请(bu)多(yao)指(pen)教(wo)。

最近迷上了背包,感觉这是一个对初学者非常友好的算法,毕竟只需要套模板。直到我遇到了分组背包······

LUOGU P1757 通天之分组背包

其实分组背包对本蒟蒻来说也是套模板,但我弱到连套模板都做不出来······

分组背包与普通01背包的区别在于每件物品有属于自己的组别,且每组的物品互斥。这意味着每组中我们最多只能取一件物品。

做得时候感觉自己脑壳炸裂,做完之后发现好像与01背包也没啥不一样。关键在于理解每层循环的意义。

贴一下我的AC代码:

#include
#include
using namespace std;
int main()
{
	int m, n;
	cin >> m >> n;
	int t[101] = { 0 };										//数组t下标表示组别,对应的数值为该组的物品数量
	int f[10000] = { 0 };								
	int w[100][1010], v[100][1010];							//价值和体积二维数组,方便分组
	int x, y, z;											//x、y、z分别代表体积,价值和组别
	int d = 0;												//用d来获取组数
	for (int i = 1; i <= n; i++) {
		cin >> x >> y >> z;
		t[z]++;
		d = max(d, z);
		w[z][t[z]] = x;
		v[z][t[z]] = y;
	}
	for (int i = 1; i <= d; i++){							//这层循环是对每组的遍历
		for (int j = m; j >= 0; j--) {
			for (int k = 1; k <= t[i]; k++) {				//这层循环是遍历每组中的物品
				if(j>=w[i][k])
				f[j] = max(f[j], f[j - w[i][k]] + v[i][k]);	//01背包的状态转移方程
			}
		}
	}
	cout << f[m] << endl;
	return 0;
}

你可能感兴趣的:(背包,算法)