HOJ 1485A Good Helper 01背包

原题: 
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[N]-d)<=C) printf("Need a helper\n");
        else printf("No\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值