您的位置:首页 > 编程语言 > Go语言

HOJ 1485A Good Helper 01背包

2014-08-03 00:29 344 查看
原题:

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

解题思路:

学了一天的背包做个小题这个费劲,想了三个小时才把这个小题想出来。



题中有两个人与一个临时工

,临时工可以开挂搬动任意一个任意重量的东西,他是最后要考虑的因素,即到底需不需要找他来。

对两人中的任一个做01背包,当时做的时候卡住的原因是背包九讲上讲的01背包有某一物品放入背包的花费跟价值,从而找到包里的最大价值,但是这个题只给了重量,就傻眼了,少了一个要素怎么做,

学算法学傻了快。之所以对他们做01背包就是为了找到他们能背的最大重量,所以重量不就是书上对应的价值么,即花费跟价值是一个东西。dp[i][j]中存的就是所能装的最大的重量。

对一个人做完01背包后,看剩余的东西是否能被另一个人一次背走,如果不能就喊来临时工

,让他把最大的东西搬走,这是必然的。

然后再看这时候能否被第二个人背走。按道理来说是要做两次01背包:1.不叫临时工时背一次,判断一次第二个人能不能背走,2.若要叫临时工就会打乱原来的计划,就要从新背一次。其实不需要的,下面代码处讲
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int A,C;//两个人的背包
int N;
int a[205];
int dp[1001];
bool cmp(int a,int b)//为找最大的直接就给排序了一遍,不知道不排会不会更快一点
{
    if(a>b)
        return true;
    return false;
}
int main()
{
    int Max,b,c,num,flag,d;
    while(scanf("%d%d",&A,&C)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        num=0;
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
        {
            scanf("%d",&a[i]);
            num+=a[i];
        }
        sort(a+1,a+N+1);
        for(int i=1;i<=N;i++)//这里对二维进行降序处理了,所以第二层循环是从大到小循环的,所以进行max判断以前的dp[j]就相当于dp[i-1][j],
而dp[N-1][A]正是临时工背走最大的东西之后的第一个能背的最大的重量,所以直接用一个变量d把dp[N-1][A]存一下就行了 
        {
            for(int j=A;j>=a[i];j--){
                     d=dp[A];//
                dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
            }
        }
        if ((num-dp[A])<=C) printf("Yes\n");
        else if ((num-a
-d)<=C) printf("Need a helper\n");
        else printf("No\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: