哈理工OJ 1333GG的关心(01背包)

37 篇文章 0 订阅

题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1333

GG的关心
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submit: 171(50 users) Total Accepted: 51(35 users) Rating: Special Judge: No
Description
电脑买回来后,MM一直用它专心的搞ACM,看着MM专注的样子,GG也是非常开心,但害怕MM劳累过度影响身体,于是GG经常到超市给MM买一些营养品来补充身体能量。GG到超市购物从来都是刷卡的,可是这种卡很诡异,当用它在超市购物的时候,刷卡机会先判断卡上的余额是否低于5元钱。如果低于5元钱则无法购买任何物品,即使那件物品的金额是小于5的也不可以。而如果卡上的金额大于等于5元则可以进行交易,即使交易成功后卡中余额为负数也是可以的。

现在超市有n种物品,每种物品最多只能买一个。已知每种物品的价格和卡上的余额。问最少可使卡上的余额为多少。

Input
输入包含多组数据。对于每一组数据:

第一行有两个正整数n和m,分别代表物品的种类数,以及卡中的余额。

第二行包含n个正整数p1,p2,p3…pn,分别代表每一种物品的价格。

当n为0时表示输入结束

范围:

m, n <= 1000

pi <= 50 (1 <= i <= n)

Output
对于每组输入,输出一个整数并换行,代表卡上可能的最小余额。

Sample Input
1 5
50
10 50
1 2 3 2 1 1 2 3 2 1
0
Sample Output
-45
32
Hint
买东西是一件一件买。
Source
2012 Spring Contest 5 - Binary Search, Greedy, DP

【思路分析】首先判断一下m是不是大于5,如果m小于5的话,直接输出m的值。否则的话,找出这n种菜种价值最大的那一个,然后对剩余的菜进行(m-5)的01背包,直接求出m-5可以买菜花费的最大钱数,然后用总价值减去dp[m-5]-最大的那个菜就是答案了。
【AC代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

int n,m,p[1005],dp[1005];

int main()
{
    while(~scanf("%d",&n))
    {
        if(n==0)break;
        scanf("%d",&m);
        int maxn=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&p[i]);
            maxn=max(maxn,p[i]);
        }
        sort(p+1,p+n+1);
        if(m<5)
        {
            printf("%d\n",m);
            continue;
        }
        memset(dp,0,sizeof(dp));
        for(int i=1;i<n;i++)
        {
            for(int j=m-5;j>=p[i];j--)
            {
                dp[j]=max(dp[j],dp[j-p[i]]+p[i]);
            }
        }
        printf("%d\n",m-dp[m-5]-maxn);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值