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

题目意思:
有n种物品,每种可能有多个,每个有不同体积和价值。初始手中有V的背包,现将所有种类至少一个装进背包中,若无法达到目标输出Impossible,否则输出最大的价值。

思路:

原始的分组背包问题是每种选或不选,而且选的话只能选一个。而这道题是每种必选,选的话可以选多个。

选多个的条件很容易,把分组背包for V 和 for 第i个  互换一下层数即可。

必选的条件有点难度,若必选的话,那么dp[i][j]由dp[i][j-v[k]]和dp[i-1][j-v[k]]转移即 在第i组中去掉v[k]体积和在前i-1组中去掉v[k]体积,在取max时不能用max(dp[i-1][j],dp[i-1][j-v[k]]+w[k]),因为这种max的意思是这组可能不选任何一个,所以需要用max(dp[i][j],dp[i-1][j-v[k]+w[k])。

初始dp为-1,当dp=-1时这个状态是不可行的,不能转移,这个是判断是否能达到目标。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 #include <cmath>
 8 #include <set>
 9 using namespace std;
10
11 #define N 105
12
13 int max(int x,int y){return x>y?x:y;}
14 int min(int x,int y){return x<y?x:y;}
15 int abs(int x,int y){return x<0?-x:x;}
16
17
18 struct node{
19     int v, w;
20 };
21
22 int dp[15][10005];
23 vector<node>ve[15];
24 int n;
25
26 main()
27 {
28     int i, j, k;
29     node p;
30     int V;
31     while(scanf("%d %d %d",&n,&V,&k)==3){
32         for(i=0;i<=k;i++) ve[i].clear();
33         for(i=0;i<n;i++){
34             scanf("%d %d %d",&j,&p.v,&p.w);
35             ve[j].push_back(p);
36         }
37         memset(dp,-1,sizeof(dp));
38         memset(dp[0],0,sizeof(dp[0]));
39         for(i=1;i<=k;i++){
40             for(j=0;j<ve[i].size();j++){
41                 p=ve[i][j];
42                 for(int v=V;v>=p.v;v--){
43                     if(dp[i][v-p.v]!=-1) dp[i][v]=max(dp[i][v],dp[i][v-p.v]+p.w);
44                     if(dp[i-1][v-p.v]!=-1) dp[i][v]=max(dp[i][v],dp[i-1][v-p.v]+p.w);
45                 }
46             }
47         }
48         if(dp[k][V]==-1) printf("Impossible\n");
49         else printf("%d\n",dp[k][V]);
50     }
51 }
时间: 2024-10-19 21:52:57

HDU 3033 分组背包变形(每种至少一个)的相关文章

hdu 3033 分组背包(每组至少选一个)

题意:有个小娃娃得了奖学金要去买东西,一共有n个东西分为k组,每个东西有一个花费和价值,问在每组东西至少买一个的条件下,小娃娃用他的奖学金买东西可以获得的最大价值. 思路:定义状态dp[i][v]表示在[1, i]组物品都至少有一个被购买时用v(背包容量)这么多钱能得到多少价值. 状态转移方程: if ( dp[i][v - cost[i][j]] != -1 ) dp[i][v] = max( dp[i][v], dp[i][v - cost[i][j]] + val[i][j] ); if

HDU 3033 分组背包

http://www.hgy413.com/1319.html 简介DeviceIoControl的三种通信方式 HDU 3033 分组背包,布布扣,bubuko.com

HDU 3033 组合背包变形 I love sneakers!

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

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 4381(背包变形)

题意: 给定n个块,编号从1到n,以及m个操作,初始时n个块是白色. 操作有2种形式: 1 ai xi : 从[1,ai]选xi个块,将这些块涂白. 2 ai xi:从[ai,n]选xi个块,将这些块涂白. 可以忽略某些操作且如果区间内没有足够的黑块(黑块用于涂白),则不能进行这个操作. 分析: 写写画画一看就知道这道题是一个背包问题. “恰好装满背包”. 以下摘自题解: 本题难点在于正确处理两种操作,不妨假设只有一种操作,那么这种操作如果是1的话那么就把操作按照a从小到大排序,每次都尽量往最左

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

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

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

hdu 1712 分组背包

背景:1Y,01背包多加了一个挑选循环而已. 分组背包的典型描述:对于很多背包,把它分为k个组,每个组内的组员是相互冲突的,所以只能选择一个. 我的代码: #include<cstdio> #include<iostream> #include<cstring> using namespace std; int main(void){ int n,m; while(scanf("%d%d",&n,&m),n*n+m*m){ int c

HDU 4341 分组背包

B - Gold miner Time Limit:2000MS Memory Limit:32768KB     Description Homelesser likes playing Gold miners in class. He has to pay much attention to the teacher to avoid being noticed. So he always lose the game. After losing many times, he wants you