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 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

分组背包

代码如下:

#include <cstdio>
#include <cstring>
int max(int a,int b)
{
    if(a > b)
        return a;
    return b;
}
struct M
{
    int m,v;
}m[17][147];
int main()
{
    int i,j,k,KK,N,MM;
    int num[147],dp[11][10047];
    int vv,mm;
    while(~scanf("%d%d%d",&N,&MM,&KK))
    {
        memset(num,0,sizeof(num));
        memset(dp,-1,sizeof(dp));
        for(i = 0 ; i < N ; i++)
        {
            scanf("%d%d%d",&k,&mm,&vv);
            m[k][num[k]].m = mm;
            m[k][num[k]].v = vv;
            num[k]++;
        }
        for( i = 0 ; i <= MM ;i++)
        {
            dp[0][i] = 0;
        }
        for(k = 1 ; k <= KK ; k++)
        {
            for( i = 0 ; i < num[k] ; i++)
            {
                for(j  = MM ; j >= m[k][i].m ; j--)
                {
                    if(dp[k][j-m[k][i].m] != -1)
                    {
                        dp[k][j] = max(dp[k][j],dp[k][j-m[k][i].m]+m[k][i].v);
                    }
                    if(dp[k-1][j-m[k][i].m] != -1)
                    {
                        dp[k][j] = max(dp[k][j],dp[k-1][j-m[k][i].m]+m[k][i].v);
                    }
                }
            }
        }
        if(dp[KK][MM] == -1)
            printf("Impossible\n");
        else
            printf("%d\n",dp[KK][MM]);
    }
    return 0;
}

hdu3033 I love sneakers!分组背包

时间: 2024-10-24 12:15:19

hdu3033 I love sneakers!分组背包的相关文章

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

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

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

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 wan

HDU 3033 I love sneakers! (01背包+反分组背包)

题意:给你 n,m,k,表示有k种鞋子共n双,你有m的容量: 每双鞋子有容量p和价值v:问是否买全k种鞋子,若能在容量为m的情况下最多能买到鞋子的价值为多少: 每双鞋子只能买一次(01背包),每种鞋子至少买一种(分组背包:每组只能有一个)与传统分组背包的限制相反. 注意初始化!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map&g

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

【hdu3033】分组背包(每组最少选一个)

[题意] 有S款运动鞋,一个n件,总钱数为m,求不超过总钱数且每款鞋子至少买一双的情况下,使价值最大.如果有一款买不到,就输出"Impossible". 1<=N<=100  1 <= M<= 10000 [题解] 首先明显这是一个分组背包. impossible 就直接看看每组最便宜的是否买得起. 因为每组最少选一个,所以我们可以这样dp: f[k][j]表示当前扫到第k组,容量为j. f[k][j]可由三个更新: f[k][j]=f[k][j] 不选当前物品

【HDU】I love sneakers!(分组背包)

看了许多的题解,都有题目翻译,很不错,以后我也这样写.直接翻译样例: 1 1 4 6 /*鞋子的数量N[1, 100]; 拥有的金钱M[1, 1w]; 品牌数目[1, 10]*/ 2 2 5 7 /*以下四行是对于每双鞋的描述*/ 3 3 4 99 /*品牌种类a; 标价b; 高兴程度增加量c*/ 4 1 55 77 5 2 44 66 6 7 /*每一种品牌的鞋子最少买一双,求最大的高兴程度*/ 很容易看出是分组背包的题型,trick是价格可能为0(居然有免费的),所以注意dp转移数组初始化-

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

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