HIT1485 A Good Helper(0-1背包)

终于补完第二次期末考了……果然考场上心态不好导致好多会做的题都没时间写

题目链接:

  http://acm.hit.edu.cn/hoj/problem/view?id=1485

题目描述:

A Good Helper

Submitted : 713, Accepted : 320

Abraham and Calford are Moving their things from dormitory A11 to A9,and they have their own carry limit,they can‘t carry things which is beyond their limit and they will not carry one bag together. They want things to be carried in one time,when they can‘t deal with so many things, they will hire a good helper to help them, who can only carry one bag of things, regardless of the weight of it. Your task is to tell whether they can carry their bags in one time,or not.

Input
There are multiple test cases.
First line of each test case contains two nonnegative numbers, A and C, (0 < A,C <=1000) representing the limit of Abraham and Calford,then the second line contains an integer N ( 0 < N <= 200 ) ,representing the number of bags,followed by N positive integers,each of them is not more than 100.

Output
For each test case
Output "Yes" if they can carry the bags without the help of the helper in one time. 
Output "Need a helper" if they can only carry the bags with the help of the helper in one time.
Output "No" if they can‘t carry the bags in one time.

Sample Input

7 7
3 5 5 5
7 7
3 5 2 5
7 7
3 7 8 7
7 7
3 7 8 9

Sample Output

Need a helper
Yes
Need a helper
No

题目大意:

  两个人搬东西,给你各自能搬的最大重量,这时如果还剩一个东西搬不动,可以请一个帮手,帮手只能搬一个东西但不限重量

  问能否一次办完并是否需要帮手

思路:

  先贪心取得最大重量得物品给帮手搬,求出剩下的和

  以A的容量做0-1背包,看剩下的容量C能否搬动

  如果C的容量减去剩余的容量还能把帮手手中的物品搬动,则不需要帮手

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int N = 210;
 8
 9 int num[N], dp[5 * N] = { 0 };
10
11 int main() {
12     int A, C, n, sum, best, res;
13     while (cin >> A >> C) {
14         cin >> n;
15         sum = best = 0;
16         for (int i = 1; i <= n; ++i) {
17             scanf("%d", &num[i]);
18             sum += num[i];
19             if (num[i] > best) { best = num[i]; res = i; }
20         }
21         sum -= best;    //除去最大后的剩余和
22         memset(dp, 0, sizeof(dp));
23         for (int i = 1; i <= n; ++i) if (i != res)    //0-1背包
24             for (int j = A; j >= num[i]; --j)
25                 dp[j] = max(dp[j], dp[j - num[i]] + num[i]);
26         if (sum - dp[A] > C)printf("No\n");    //有帮手C也拿不动
27         else if (sum - dp[A] + best <= C)printf("Yes\n");    //C还可以再拿帮手拿的那个东西
28         else printf("Need a helper\n");    //C拿不动最大的东西,但剩下的可以和A分掉
29     }
30 }
时间: 2024-08-27 02:38:15

HIT1485 A Good Helper(0-1背包)的相关文章

poj1417 带权并查集+0/1背包

题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是魔. 对于这些问题,我们只需要发现,如果回答对方是魔,那么即可以判断出这两个不是同一种族,而如果回答对方是神,那么说明这两个是同一种族,那么就可以用带权并查集合并这些神和魔,然后记录两种分别多少个,这样当所有询问都处理完时我们就可以得到一系列的集合,每个集合分别有它的两个种族的人数,但是此时对于每个

NOJ 1860 保研(0/1背包概率dp)

保研 时间限制(普通/Java):1000MS/3000MS         运行内存限制:65536KByte 总提交:171          测试通过:40 题目描述 对于一些名校而言,保研不仅可以由学校推免,也可以由学生自己向希望保研的学校提出申请,这个过程有点类似于外国学生向学校提交简历等待Offer的过程.但是,投递申请需要亲自去相应学校的研招办递交材料,这就需要一些成本(比如路费等),且每个院校都有自己的录取成功率.现在,请在总成本不超过限制的情况下,求出最大的成功率. 输入 输入

POJ 1636 Prison rearrangement DFS+0/1背包

题目链接: POJ 1636 Prison rearrangement Prison rearrangement Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 2194   Accepted: 984 Description In order to lower the risk of riots and escape attempts, the boards of two nearby prisons of equal

POJ 3628 Bookshelf 2 0/1背包和DFS两种解法

题目链接:POJ 3628 Bookshelf 2 Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7462   Accepted: 3436 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly,

牛客网 TaoTao要吃鸡 ( 0/1背包变形 )

题意 : 题目链接 分析 :  如果没有 BUG (即 h == 0 的时候)就是一个普通的 0 / 1 背包 需要讨论一下 h != 0 的情况 此时有就相当于有物品是有特权的 而且背包装有特权的物品根据题目的要求是应当最后装的 也就是说特权物品装完之后背包将不再可装 所以特权物品肯定是只有一个的 数据量并不大,所以可以去枚举这个特权物品 那么如何知道在  没有装特权物品  之前的最佳选择方案? 答案就是用最小的可剩空间留给特权物品,然后其他空间去跑 0/1 背包 最小的可剩空间当然就是 h

浙大PAT CCCC L3-001 凑零钱 ( 0/1背包 &amp;&amp; 路径记录 )

题目链接 分析 : 就是一个 0/1 背包,但是需要记录具体状态的转移情况 这个可以想象成一个状态转移图,然后实际就是记录路径 将状态看成点然后转移看成边,最后输出字典序最小的路径 这里有一个很巧妙的做法 先将所有的硬币升序排序(这一点很重要) 然后在这一条件下,假设当前状态是考虑第 i 个硬币,前一个状态是考虑第 i-1 个硬币 试想对于同一个体积,如果选用的硬币数量越多是不是字典序更小 然后对于如果对于同一体积下,选用硬币数一样多的两种方案 由于我们已经升序排序,如果有一样多硬币的情况,那么

POJ 1745 【0/1 背包】

题目链接:http://poj.org/problem?id=1745 Divisibility Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13431   Accepted: 4774 Description Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequen

hdu 2191 悼念512同胞(0 1背包)

Input 输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格.每袋的重量以及对应种类大米的袋数. Output 对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完.每

0 1背包模板

# include <stdio.h> # include <stdlib.h> # include <string.h> # define max(x,y) x>y?x:y; int v[1001];//价值 int w[1001];//重量 int dp[1001][1001]; int main() { int n,m; while(scanf("%d%d",&m,&n)!=EOF) { memset(dp,0,sizeo