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 ( dp[i - 1][v - cost[i][j]] != -1 )
    dp[i][v] = max( dp[i][v], dp[i - 1][v - cost[i][j]] + val[i][j] );

  分别表示第i组的物品不是和是第一次购买。

  这两个状态转移方程顺序不能变,因为有花费是0的物品...

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5
 6 const int N = 101;
 7 const int M = 10001;
 8 const int K = 11;
 9 int dp[K][M];
10 int cost[K][N];
11 int val[K][N];
12 int num[K];
13
14 int main ()
15 {
16     int n, m, k;
17     while ( scanf("%d%d%d", &n, &m, &k) != EOF )
18     {
19         memset( num, 0, sizeof(num) );
20         for ( int i = 1; i <= n; i++ )
21         {
22             int g;
23             scanf("%d", &g);
24             scanf("%d%d", &cost[g][num[g]], &val[g][num[g]]);
25             num[g]++;
26         }
27         memset( dp, -1, sizeof(dp) );
28         memset( dp[0], 0, sizeof(dp[0]) );
29         for ( int i = 1; i <= k; i++ )
30         {
31             for ( int j = 0; j < num[i]; j++ )
32             {
33                 for ( int v = m; v >= cost[i][j]; v-- )
34                 {
35                     if ( dp[i][v - cost[i][j]] != -1 )
36                     {
37                         dp[i][v] = max( dp[i][v], dp[i][v - cost[i][j]] + val[i][j] );
38                     }
39                     if ( dp[i - 1][v - cost[i][j]] != -1 )
40                     {
41                         dp[i][v] = max( dp[i][v], dp[i - 1][v - cost[i][j]] + val[i][j] );
42                     }
43                 }
44             }
45         }
46         if ( dp[k][m] != -1 )
47         {
48             printf("%d\n", dp[k][m]);
49         }
50         else
51         {
52             printf("Impossible\n");
53         }
54     }
55     return 0;
56 }
时间: 2024-10-19 21:53:02

hdu 3033 分组背包(每组至少选一个)的相关文章

HDU 3033 分组背包

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

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

【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 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 3535 分组背包

题意: 有n组工作,现在有T分钟时间去做一些工作.每组工作里有m个工作,并且类型为s,s类型可以为0,1,2,分别表示至少选择该组工作的一项,至多选择该工作的一项,不限制选择.每个工作有ci,gi两个属性,表示需要花费ci时间去完成该项工作,完成后将会获得gi的快乐值,现在求快乐值最大多少,如果不能完成工作,输出-1: 原题如下: AreYouBusy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java

hdu 1712 分组背包入门

对于每门课程,学习的时间不同,收获也不同,在一门课程上花费了两个不同的时间去学习是互斥的,即它们是属于同一个组内的物品,直接做分组背包即可. 需要注意三重循环的顺序不可变! 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = -99999999; 7 const int N = 101; 8 int a[N][N

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

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