网络上题解很多。我就不乱说了。
首先分组背包的原型:
给物品分组,容量为V的背包,每个分组内的物品互斥,每个分组最多取一个物品。求最大值。
代码很简单:
for( int i=0;i<group;i++ )
for( int j=V;j>=0;j-- )
for( int k=0;k<total[i];k++ )
f[V]=max( f[V],f[V-cost[k]]+value[k] );
背包九讲里面有,相信大家都看了。不多说。
而这题,是在每个分组中最少取一种物品。
so~ 不能用一维了,+一个维度来表示分组。当前分组会对下一分组有影响。
so DP方程为:当前的01背包,上一组的01背包....;两次去最值就好了。
Code:
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
struct node
{
int group,cost,value;
}good[111];
bool cmp( node a,node b ){ return a.group<b.group; }
int max( int a,int b ){ return a>b?a:b; }
int min( int a,int b ){ return a<b?a:b; }
int main()
{
int N,G,V;
int f[11][11111];
while( scanf( "%d %d %d",&N,&V,&G )!=EOF )
{
memset( f,0,sizeof(f) );
for( int i=0;i<N;i++ )
scanf( "%d %d %d",&good[i].group,&good[i].cost,&good[i].value );
sort( good,good+N,cmp );
int j=0;
for( int i=0;i<N;i++ )
for( int k=V;k>=good[i].cost;k-- )
{
int g=good[i].group;
int c=good[i].cost;
int v=good[i].value;
f[g][k]=max( f[g][k],f[g][k-c]+v );
f[g][k]=max( f[g][k],f[g-1][k-c]+v );
}
if( f[G][V] )
printf( "%d\n",f[G][V] );
else
printf( "Impossible\n" );
}
return 0;
}