HDU 2546 饭卡 (01背包问题)

还是基础的01背包,带了一点转换的思想、


由于题意要求的是只有饭卡金额大于等于5元,就可以买任何金额的菜、并且卡里面的金额可以为负数,求最少卡里会剩余多少钱。 由此我们可以按照dp的思想来求饭卡原本的余额m-5元 在n-1个道菜中,最多可以买的菜花掉的最大值,此时便剩余最后一道菜,也就是最贵的菜,并且我饭卡里的钱一定是大于等于5元的,所以我可以买最后一道菜、由此可知我们的答案便为m-dp[m-5]-w[n-1]  ( m为饭卡里面初始的金额,dp[m-5]为我从n-1道菜里面买出我花费最大的金额的数量,w[n-1]为我最后购买了最贵的菜)、 还需要考虑的最后一个问题就是我饭卡里面的金额不是大于5的情况,不大于5的时候并不可以买任何一道菜,所以,直接输出便可、


AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1100;
int n,m;
int w[maxn];
int dp[maxn];
int main()
{
    while(scanf("%d",&n)&&n){
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
            scanf("%d",&w[i]);
        scanf("%d",&m);
        sort(w,w+n);
        for(int i=0;i<n-1;i++){
            for(int j=m-5;j>=w[i];j--){
                dp[j]=max(dp[j],dp[j-w[i]]+w[i]);
            }
        }
        if(m<5)
            printf("%d\n",m);
        else
            printf("%d\n",m-dp[m-5]-w[n-1]);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值