分组背包问题的变形,将至多从背包选取一个改为至少从背包选取一个,修改第二重和第三重循环的顺序即可
/*分组背包,且每个背包至少选择一个,交换2,3层循环次序*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int f[105][10005];
int brand[105];
int c[105];
int w[105];
const int inf = 10000000;
int main()
{
int n,m,k;
while(scanf("%d %d %d",&n,&m,&k)!=EOF)
{
memset(brand,0,sizeof(brand));
memset(c,0,sizeof(c));
memset(w,0,sizeof(w));
memset(f,0,sizeof(f));
for(int i = 1;i<=n;i++)
{
scanf("%d %d %d",&brand[i],&c[i],&w[i]);
}
for(int i = 1;i<105;i++)
for(int j = 1;j<10005;j++)
{
f[i][j] = -inf;
}
for(int i = 1;i<=k;i++)
for(int j = 1;j<=n;j++)
for(int v = m;v>=c[j];v--)
{
if(brand[j]==i)
{
f[i][v] = max(f[i][v],f[i][v-c[j]]+w[j]);
f[i][v] = max(f[i][v],f[i-1][v-c[j]]+w[j]);
}
}
if(f[k][m]<0)
printf("Impossible\n");
else
printf("%d\n",f[k][m]);
}
return 0;
}