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][j]更新
 5 //显然,后一种情况应该后更新
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <iostream>
 9 #include <queue>
10 #include <cmath>
11 #include <vector>
12 #include <algorithm>
13 using namespace std;
14 /**
15   * This is a documentation comment block
16   * 如果有一天你坚持不下去了,就想想你为什么走到这儿!
17   * @authr songt
18   */
19 const int imax_n = 15;
20 const int imax_v = 10005;
21 struct node
22 {
23     int weight,value;
24 };
25 vector<node > vec[imax_n];
26 int dp[imax_n][imax_v];
27 int n,v;
28 int k;
29 int max(int a,int b)
30 {
31     return a>b?a:b;
32 }
33 void Dp()
34 {
35     memset(dp,-1,sizeof(dp));
36     //for (int i=0;i<=k;i++)
37     //for (int j=0;j<=v;j++)
38     //dp[i][j]=-1;
39     for (int i=0;i<=v;i++)
40     {
41         dp[0][i]=0;
42     }
43     for (int i=1;i<=k;i++)
44     {
45         for (int j=0;j<vec[i].size();j++)
46         {
47             for (int l=v;l>=vec[i][j].weight;l--)
48             {
49                 if (dp[i][l-vec[i][j].weight]!=-1)
50                 {
51                     dp[i][l]=max(dp[i][l],dp[i][l-vec[i][j].weight]+vec[i][j].value);
52                 }
53                 if (dp[i-1][l-vec[i][j].weight]!=-1)
54                 {
55                     dp[i][l]=max(dp[i][l],dp[i-1][l-vec[i][j].weight]+vec[i][j].value);
56                 }
57             }
58         }
59     }
60     if (dp[k][v]==-1)
61     {
62         printf("Impossible\n");
63     }
64     else
65     {
66         printf("%d\n",dp[k][v]);
67     }
68 }
69 int main()
70 {
71     while (scanf("%d%d%d",&n,&v,&k)!=EOF)
72     {
73         int kind;
74         node x;
75         for (int i=1;i<=10;i++)
76         vec[i].clear();
77         for (int i=1;i<=n;i++)
78         {
79             scanf("%d%d%d",&kind,&x.weight,&x.value);
80             vec[kind].push_back(x);
81         }
82         Dp();
83     }
84     return 0;
85 }

时间: 2024-10-12 20:11:42

hdu3033 分组背包的相关文章

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

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

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

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

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

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

VijosP1250:分组背包

背景 Wind设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了~ 描述 机器人们都想知道谁是最勇敢的,于是它们比赛搬运一些物品. 它们到了一个仓库,里面有n个物品,每个物品都有一个价值Pi和重量Wi,但是有些物品放在一起会爆炸,并且爆炸具有传递性.(a和b会爆炸.b和c会爆炸则a和c会爆炸)机器人们可不想因此损失自己好不容易从Wind那里敲诈来的装备,于是它们想知道在能力范围内,它们最多可以拿多少价值的物品. 你能帮助它们吗? 格式 输入格式 每组测试数据第1行为n,Wmax,

HDU-1011 Starship Troopers (树形DP+分组背包)

题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<iostream> # include<cstdio> # include<vector> # include<cstring> # include<algorithm> using namespace std; const int N=105; const

HDU 4003 Find Metal Mineral (树形DP,树形分组背包,经典)

题意:给定一棵树图,n个节点,有边权,要派k<11个机器人从节点s出发,遍历所有的点,每当1只机器人经过1条边时就会花费该边的边权,边是可重复走的.问遍历完所有点的最小花费? 思路: 非常经典,首先需要知道一点,才能往下推理.就是“如果在t点派c个机器人往孩子u,那么最多只有1个机器人能走会回来到t,否则花费总是不划算的”. 稍微证明一下: (1)假设派1个机器人往u,逛一圈回到u的父亲t,花费v= 子树u的边权和*2 + e(t,u)*2.若机器人不要了,那花费肯定比v还要少. (2)假设派2

HDU 1712 ACboy needs your help-dp-(分组背包模型)

题意:n门课程用m天来学习,每门课用不同的天数来学习会有不同的学分,求能得到的最大的学分 分析:第一次接触分组背包.分组背包的模型就是不同的物品有不同的花费和价值,求在规定花费内能得到的最大的价值,这前面跟以前的背包最大的不同是物品分为几组,每组内的物品最多只能选一种:dp[i][j]表示前i组花费j能得到的最大的价值,不过实际在做的时候用一维数组就可以了 公式: for 组i for 花费j (从大到小) for 组内物品k if(j>=c[k]) dp[j]=max(dp[j],dp[j-c