思路:
看到这个题的时候,先想到的是分组背包,但是有一些限定,每样至少买一个,所以,这又想到了昨天写的那个二维背包里面的限定方法,把所有的之都赋成-1,把当前满足条件的情况,也就是编号为0的值全都赋值为0 ,后面再根据前面的值确定是否满足限定,接下来,就是【分组—01】背包的思路了,这个题自己做的时候有点水分,所以写下了,以后再做几遍,以加强自己的理解。
代码:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include<iostream>
#include <algorithm>
using namespace std;
#define maxn 10005
//#define LOCAL
#define CLR( a , b ) memset( a,b ,sizeof(a) )
int dp[11][maxn] , c[100] , v[100] , N , M , K , Bag[11][101] , Sum[11] ;
int main() {
#ifdef LOCAL
freopen("Input.txt","r",stdin);
freopen("Output.txt","w",stdout);
#endif
int i , j , k , x ;
while( ~scanf( "%d%d%d" , &N , &M , &K) ){
CLR( Sum , 0 ) ;
CLR( dp , -1 ) ;
for( i = 0 ; i < N ; i++ ){
scanf( "%d%d%d" , &x , &c[i] , &v[i] ) ;
Bag[x][ Sum[x] ] = i ; //记录到该品牌
Sum[x] ++ ; //控制个数
}
for( i = 0 ; i <= M ; i++ ) //初始化
dp[0][i] = 0 ;
for( i = 1 ; i <= K ; i++ ) //品牌编号
for( j = 0 ; j < Sum[i] ; j++ ) //该编号个数
for( k = M ; k >= c[Bag[i][j]] ; k-- ){
if( dp[i][ k-c[ Bag[i][j] ] ] != -1 )
dp[i][k]=max(dp[i][k],dp[i][k-c[Bag[i][j]]]+v[Bag[i][j]]);
if( dp[i-1][ k-c[ Bag[i][j]] ] != -1 )
dp[i][k]=max(dp[i][k],dp[i-1][k-c[Bag[i][j]]]+v[Bag[i][j]]);
}
if( dp[K][M] < 0 )
printf( "Impossible\n" ) ;
else
printf( "%d\n" , dp[K][M] ) ;
}
return 0;
}