【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] 不选当前物品

f[k][j]=f[k-1][j-b[i]]+c[i] 选择当前物品,并且是在该组中第一次选物品

f[k][j]=f[k][j-b[i]]+c[i] 选择当前物品,并且不是在该组中第一次选

因为f[k][j]初始值为0,所以它最少都会买一样东西(由第二条更新得到)

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<vector>
 8 using namespace std;
 9
10 const int N=11000,S=110;
11 int n,m,K,a[N],b[N],c[N],mn[S],d[S][S],f[S][N];
12
13 int maxx(int x,int y){return x>y ? x:y;}
14 int minn(int x,int y){return x<y ? x:y;}
15
16 int main()
17 {
18     freopen("a.in","r",stdin);
19     while(scanf("%d%d%d",&n,&m,&K)!=EOF)
20     {
21         memset(d,0,sizeof(d));
22         memset(mn,63,sizeof(mn));
23         for(int i=1;i<=n;i++)
24         {
25             scanf("%d%d%d",&a[i],&b[i],&c[i]);
26             d[a[i]][++d[a[i]][0]]=i;
27             mn[a[i]]=minn(mn[a[i]],b[i]);
28         }
29         int x=0;
30         for(int i=1;i<=K;i++) x+=mn[i];
31         if(m<x) printf("Impossible\n");
32         else
33         {
34             memset(f,0,sizeof(f));
35             for(int k=1;k<=K;k++)
36             {
37                 for(int i=1;i<=d[k][0];i++)
38                 {
39                     x=d[k][i];
40                     for(int j=m;j>=b[x];j--)
41                     {
42                         f[k][j]=maxx(f[k][j],maxx(f[k-1][j-b[x]]+c[x],f[k][j-b[x]]+c[x]));
43                     }
44                 }
45             }
46             printf("%d\n",f[K][m]);
47         }
48     }
49     return 0;
50 }
时间: 2024-11-08 18:56:49

【hdu3033】分组背包(每组最少选一个)的相关文章

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

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6. 1 class Solution { 2 public int maxSubArray(int[] nums) { 3 int sum=nums[0];//当前遍历到的最大和的子集 4 int max=nums[0];//数组的最大和 5 for(int i=1;i<nums.length;i++){ 6 sum=sum>0?(sum+nums[i]):n

hdu3033 分组背包

1 //Accepted 896 KB 156 ms 2 //http://blog.csdn.net/juststeps/article/details/8712150 3 //dp[i][l]=max(dp[i][l],dp[i][l-v[i][j].weight]+v[i][j].value);第i种已经取数后用v[i][j]更新 4 //dp[i][l]=max(dp[i][l],dp[i-1][l-v[i][j].weight]+v[i][j].value);第i种还没有取数用v[i]

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

#383 Div1 Problem B Arpa&#39;s weak amphitheater.... (分组背包 &amp;&amp; 并查集)

题意 : 有n个人,每个人都有颜值bi与体重wi.剧场的容量为W.有m条关系,xi与yi表示xi和yi是好朋友,在一个小组. 每个小组要么全部参加舞会,要么参加人数不能超过1人. 问保证总重量不超过W,剧场中的颜值最大能到多少? 分析 : 很显然的分组背包题目, 不过有所不同, 先来回顾一下普通的分组背包的描述 给出一个背包,背包有容量C,再给出N组物品,每组物品有ki种,每种物品有对应的体积Vi,价值Pi,每组物品至多选一种,且最多取一件.求用背包装物品,能获得的最大总价值是多少.可以发现和上

hdu 1561 树形dp+分组背包

题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m)时选最多的宝物,而一个子节点中只可以选择一个状态进行转移,每个节点有若干个子节点,问题就转换为分组背包,几个子节点就是几个分组背包,体积是选几个地点,价值是宝物价值. 状态转移方程: dp[v][1] = Money[v]; (v为叶子节点)                    dp[v][j] = m

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

【hdu1712】分组背包(每组最多选1个)

[分组背包] [题意]ACboy要开始选课了,上一门课能够获得的收益和他上这门课的时间是有关的,然后给你若干门课,让你帮他进行选课,每一门课自然是只能选择一个课程时长,问你如何选择,才能使ACboy获得的受益最大. for(k=1;k<=K;k++) for(int v=V;v>=0;v--) for(int i=item in group k) f[v]=max(f[v],f[v-c[i]+w[i]);保证用到的都是k-1所更新的而不是k所更新的. 1 #include<cstdio&

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