hdu3033---I love sneakers!(分组背包变形)

Problem Description

After months of hard working, Iserlohn finally wins awesome amount of scholarship. As a great zealot of sneakers, he decides to spend all his money on them in a sneaker store.

There are several brands of sneakers that Iserlohn wants to collect, such as Air Jordan and Nike Pro. And each brand has released various products. For the reason that Iserlohn is definitely a sneaker-mania, he desires to buy at least one product for each brand.

Although the fixed price of each product has been labeled, Iserlohn sets values for each of them based on his own tendency. With handsome but limited money, he wants to maximize the total value of the shoes he is going to buy. Obviously, as a collector, he won’t buy the same product twice.

Now, Iserlohn needs you to help him find the best solution of his problem, which means to maximize the total value of the products he can buy.

Input

Input contains multiple test cases. Each test case begins with three integers 1<=N<=100 representing the total number of products, 1 <= M<= 10000 the money Iserlohn gets, and 1<=K<=10 representing the sneaker brands. The following N lines each represents a product with three positive integers 1<=a<=k, b and c, 0<=b,c<100000, meaning the brand’s number it belongs, the labeled price, and the value of this product. Process to End Of File.

Output

For each test case, print an integer which is the maximum total value of the sneakers that Iserlohn purchases. Print “Impossible” if Iserlohn’s demands can’t be satisfied.

Sample Input

5 10000 3

1 4 6

2 5 7

3 4 99

1 55 77

2 44 66

Sample Output

255

Source

2009 Multi-University Training Contest 13 - Host by HIT

Recommend

gaojie | We have carefully selected several similar problems for you: 2639 2844 3535 2415 3449

Statistic | Submit | Discuss | Note

这是一道分组背包的题,与普通分组背包不同的是,它要求每组的物品至少取一件而不是最多只可以取一件

我们设状态dp[i][j]表示选到第i组,花费小于等于j元的情况下,最多可以得到的价值

那么dp[i][j]有2个前驱状态,第一种是此时没有选过第i组的;第二种是此时已经选过第i组的,这样就解决了至少选1件

由于价值可以是0,所以初始化不能是0,不然最后无法判断是否是impossible,可以初始化为一个负数

由于是可以选多件,所以循环顺序就和普通的分组背包不同了

/*************************************************************************
    > File Name: hdu3033.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年05月10日 星期日 14时16分31秒
 ************************************************************************/

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>

using namespace std;

const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

int dp[11][10010];
vector <PLL> val[11];

int main() {
    int n, m, k;
    while (~scanf("%d%d%d", &n, &m, &k)) {
        memset(dp, -inf, sizeof(dp));
        for (int i = 1; i <= n; ++i) {
            val[i].clear();
        }
        int a, b, c;
        for (int i = 1; i <= n; ++i) {
            scanf("%d%d%d", &a, &b, &c);
            val[a].push_back(make_pair(b, c));
        }
        for (int i = 0; i <= m; ++i) {
            dp[0][i] = 0;
        }
        for (int i = 1; i <= k; ++i) {
            int size = val[i].size();
            for (int j = 0; j < size; ++j) {
                for (int v = m; v >= 0; --v) {
                    if (v < val[i][j].first) {
                        break;
                    }
                    if (dp[i][v - val[i][j].first] != -inf) {
                        dp[i][v] = max(dp[i][v], dp[i][v - val[i][j].first] + val[i][j].second);
                    }
                    if (dp[i - 1][v - val[i][j].first] != -inf) {
                        dp[i][v] = max(dp[i][v], dp[i - 1][v - val[i][j].first] + val[i][j].second);
                    }
                }
            }
        }
        if (dp[k][m] < 0) {
            printf("Impossible\n");
            continue;
        }
        printf("%d\n", dp[k][m]);

    }
    return 0;
}
时间: 2024-10-04 00:58:56

hdu3033---I love sneakers!(分组背包变形)的相关文章

hdu3033 I love sneakers! 分组背包变形(详解)

这个题很怪,一开始没仔细读题,写了个简单的分组背包交上去,果不其然WA. 题目分析: 分组背包问题是这样描述的:有K组物品,每组 i 个,费用分别为Ci ,价值为Vi,每组物品是互斥的,只能取一个或者不取(最多取一个),求在一定背包容量V的情况下,能够获得的最大价值. 而这个题是,他每个牌子的鞋最少会买一双,但不会买一个牌子同款的两次. 也就是说如果将每个牌子分成一组,那么在每组里面要至少取一双,所以这更像是在每组里面进行01背包. 普通的分组背包的三层循环是: for(int k=0; k<K

hdu3033 I love sneakers!分组背包

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3033 Problem Description After months of hard working, Iserlohn finally wins awesome amount of scholarship. As a great zealot of sneakers, he decides to spend all

HDU 3033 I love sneakers! 分组背包

我是个逗比...真心不是搞算法的料 不太中规中矩的分组背包,分组至少选一件商品.dp[i][j] 可以由当前dp[i-1][j-c] 和 dp[ i ][j-c]更新得到. #include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <cmath

hdu 3033 I love sneakers!(分组背包,每组至少取一件)

http://acm.hdu.edu.cn/showproblem.php?pid=3033 大致题意:某人要买鞋子,有k种鞋,要求每种鞋至少买一双,给出每双鞋子的花费和价值,问m元钱可以买到的鞋子的最大价值是多少. 思路:分组背包问题.与传统的分组背包不同:每组物品至少取一件:且每组中物品任意取. 想一想传统的分组背包,每组至多选一件: for 所有的组k     for v=V..0         for 所有的i属于组k             f[v]=max{f[v],f[v-c[i

HDU 3033 分组背包变形(每种至少一个)

I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4464    Accepted Submission(s): 1824 Problem Description After months of hard working, Iserlohn finally wins awesome amount of sc

HDU 4341 Gold miner 分组背包变形

题意: 挖金矿,人在(0,0)点 n个金子 游戏时间为T 下面n行 (x, y) cost val 且若人 和 多块金子共线时,只能先取最近的金子,依次取,就是和游戏一样的. 且所有点只在1 2象限 思路: 我们先把所有共线的点分组 对于每组的物品,我们都可以认为取这个物品的花费就是前面所有物品的花费总和,而价值就是前面所有物品的价值总和. 这样就能消除每组物品的先取后取的影响了,但有一个情况就是这组至多只能取一个物品,所以每个状态只能是取了这个物品后或者是原始状态. 用原始状态转移,然后和原始

HDU 3033 I love sneakers! 我爱运动鞋 (分组背包,01背包,严重变形)

题意:给出k家店,每家店内有各种价格的鞋子(同样的鞋子只能买一双),每双鞋子有价值,要求每家店至少买一双.给出m钱,求获得的最大价值. 思路:分组背包严重变形了,变成了相反的,每组物品至少挑1件(分组背包是至多挑1件).虽然是分组背包的变形,但是用到的却是01背包的思路.要求每家店至少买1双,那么可以只买一双双,也可以买多双.难点在这.需要维护两行dp状态值即可.第一行是前面组的物品的最佳状态,第二行是第i件物品之前的最佳状态(已经装进同组物品). 对于i组第t件物品,(1)要么从i组之前的状态

hdu3033(变形分组背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3033 题意:Iserlohn要买鞋,有k种牌子,每种牌子至少买一双鞋子.每双鞋子有标价跟实际价值.求用m多的钱买最多价值的鞋. 分析:分组背包是有k组物品,每组至多取一件或不取,用容量为v的背包装最多价值的物品.而这题是至少每组取一件. 状态方程dp[k][m] 表示已经买了k种鞋 在有m钱状态下的鞋的最大价值. 为了满足至少每组取一件,则加了这组状态转移方程: if(dp[k-1][j-b[i]]

hdu 3033 I love sneakers!【详剖 DP 之 分组背包 】

I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4538    Accepted Submission(s): 1866 Problem Description After months of hard working, Iserlohn finally wins awesome amount of s