https://www.luogu.org/problemnew/show/P1064

分组背包,由于每组里的情况很少,只有5种,所以就不需要每组内部01背包过一遍了。只需要把主件附件放到一组里,像01背包那样,只是在每组里考虑所有的组合。考虑组合时也是需要考虑一下怎么写可以简化代码的。

#include<bits/stdc++.h>
using namespace std;

int V,n;
vector<int> c[65],w[65];
int d[32005];

void ZeroOnePack()
{
	for(int i=1;i<=n;i++)
	{
		if(c[i].size()==0)continue;
		for(int j=V;j>=0;j--)
		{
			if(c[i].size()>=1)
			{
				if(j>=c[i][0])d[j]=max(d[j],d[j-c[i][0]]+c[i][0]*w[i][0]);
	        }
	        if(c[i].size()>=2)
	        {
	        	if(j>=c[i][0]+c[i][1])d[j]=max(d[j],d[j-c[i][0]-c[i][1]]+c[i][0]*w[i][0]+c[i][1]*w[i][1]);
			}
			if(c[i].size()>=3)
			{
				if(j>=c[i][0]+c[i][1]+c[i][2])d[j]=max(d[j],d[j-c[i][0]-c[i][1]-c[i][2]]+c[i][0]*w[i][0]+c[i][1]*w[i][1]+c[i][2]*w[i][2]);
			}
		}
	}
}

int main()
{
	freopen("input.in","r",stdin);
	int v,p,q;
	cin>>v>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>v>>p>>q;
		if(q==0)c[i].push_back(v),w[i].push_back(p);
		else c[q].push_back(v),w[q].push_back(p);
	}
	
	ZeroOnePack();
	cout<<d[V]<<endl;
	return 0;
}