HDU 3033 I love sneakers! (リュックサックグループ)

1830 ワード

n-物品総数、m銭数、kブランド数、aブランドbの価格c価値を説明する
各グループは1つ買わなければなりません.各アイテムは1つしかありません.
どのブランドも買わなければなりません.そうしないとimpossibleです.
step 1:まず靴をグループに分けてvectorで保存step 2:それから各グループについて単独で議論します****各グループについて:****は少なくとも1つのものを買わなければなりません.また、アイテムごとに1回しか使用できません【注意】アイテムごとに1回しか使用できません<=>お金(体積)を大きくから小さく更新することで、アイテムごとに1回しか使用できないことを保証します【注意2】、初値記号-oo(無限小)で、アイテムのお金を保証します(ボリューム)が0の場合はバグが出ないし、少なくとも1つのものを買うことも保証されています.無限の量で更新されますから.
d[i][k]は1~i種類の靴を買った(締め切り)ことを示し、
使用するお金がkで生み出す最大の価値はd[i][k];
struct Node{
       int v ;
       int money ;
};
int V  , K ;
vector<Node> Brand[11] ;
int dp[11][10008] ;

int Max(int a , int b , int c){
    if(a < b)
        a = b ;
    if(a < c)
        a = c ;
    return a ;
}

int DP(){
    int i , j , k ;
    for(i = 1 ; i <= K ; i++){
        if(Brand[i].size() == 0)
            return inf ;
    }
    for(i = 1 ; i <= K ; i++)
        for(j = 0 ; j <= V ; j++)
           dp[i][j] = -0x7fffffff ;
    for(i = 0 ; i <= V ; i++)
        dp[0][i] = 0 ;
    for(i = 1 ; i <= K ; i++){
       for(j = 0 ; j < Brand[i].size() ; j++){
          int v = Brand[i][j].v ;
          int money = Brand[i][j].money ;
          for(k = V ; k >= v ; k--){
               dp[i][k] = Max(dp[i][k] , dp[i][k-v] + money , dp[i-1][k-v] + money) ;
          }
       }
    }
    return dp[K][V] ;
}

int main(){
    int n , i , k ;
    Node node ;
    while(cin>>n>>V>>K){
        for(i = 1 ; i <= K ; i++)
            Brand[i].clear() ;
        for(i = 1 ; i <= n ; i++){
            cin>>k>>node.v>>node.money ;
            Brand[k].push_back(node) ;
        }
        if(DP() == inf)
            puts("Impossible") ;
        else
            cout<<dp[K][V]<<endl ;
    }
    return 0 ;
}