HDU 3033 I love sneakers! (分组背包变形)

题目大意:xx去买鞋,有k种牌子,然后给出n双鞋,每双鞋有它属于的牌子、价格、收藏价值。xx认为他不差钱,要求每种鞋子买一双。但实际上他只有m毛钱,问能否买到符合xx要求的鞋,能找到的话输出最大的收藏价值总和。   分组背包的变形,每种牌子要求至少选一个,这与分组背包的每组最多选一个不一样,但背包的思想都是一样的。。。 就是 状态转移的时候可以加上从上一组转移(选择1个)与本组转移(大于1个),还有注意枚举物品和枚举体积的顺序~~ 设dp[i][j]表示前i组填到容量j的最大价值, 则方程为:dp[i][j] = max(dp[i][j],dp[i-1][j-price[i][k]] + value[i][k],dp[i][j-price[[i][k]] + value[i][k])  
#include 
 
   
    
  
#include 
  
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
         
           #include 
          
            #include 
            #include 
            
              #include 
             
               #include 
              
                #define MID(x,y) ((x+y)>>1) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long LL; const int sup = 0x7fffffff; const int inf = -0x7fffffff; struct shoes{ int price; int value; }; vector 
               
                 s[11]; int f[15][10100]; int N, M, K; int main(){ while(scanf("%d %d %d", &N, &M, &K) != EOF){ for (int i = 0; i < 11; i ++) s[i].clear(); for (int i = 1; i <= N; i ++){ int tmp_brand, tmp_price, tmp_value; scanf("%d %d %d", &tmp_brand, &tmp_price, &tmp_value); shoes tmp; tmp.price = tmp_price; tmp.value = tmp_value; s[tmp_brand].push_back(tmp); } mem(f, -1); f[0][0] = 0; for (int k = 1; k <= K; k ++) for (int j = 0; j < (int)s[k].size(); j ++) for (int v = M; v >= 0; v --){ if (v-s[k][j].price >= 0 && f[k][v-s[k][j].price] != -1){ f[k][v] = max(f[k][v], f[k][v-s[k][j].price]+s[k][j].value); } if (v-s[k][j].price >= 0 && f[k-1][v-s[k][j].price] != -1){ f[k][v] = max(f[k][v], f[k-1][v-s[k][j].price]+s[k][j].value); } } int res = -1; for (int v = 0; v <= M; v ++) if (f[K][v] > res) res = f[K][v]; if (res >= 0) printf("%d\n", res); else printf("Impossible\n"); } return 0; } 
                
               
              
             
           
          
         
        
       
      
    
 
   
 

你可能感兴趣的:(love)