zoukankan      html  css  js  c++  java
  • 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;
    }
    
     
    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    win10设置删除文件提示框
    在XP系统下如何访问win10共享的打印机
    禁止删除、修改共享文件,防止局域网用户私自复制共享文件到本地的方法
    打开wps的宏设置,提示你可能没有装vba
    网络打印协议之LPR或RAW
    LPD打印机服务是什么意思
    存储备份
    EasyUI的DataGrid 打印导出
    jquery easyui datagrid使用参考
    easyUI单元格合并自定义封装
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114229.html
Copyright © 2011-2022 走看看