hdu 2546 01背包

背景:1——WA:卡上最低要求为5元才能消费的边界情况没有处理。

思路:首先判断卡上余额是否有五元,不是直接输出。然后,从卡里面拿出五元来买最大价值,剩下的钱尽可能用完就可以了。

学习:1.这里透露了一个基本问题:从n个数中选取m个数,使这m个数的和尽可能的接近k。这个体是把k看做背包的容量,把一个数的值既看做价值又看做体积,转化为01背包问题。

我的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int value[1009],F[1001];

int sum(int i,int n){
    int ok=0;
    for(;i < n;i++) ok+=value[i];
    return ok;
}

int main(void){
    int n,money,max_price=0,mp;
    while(~scanf("%d",&n),n){<span id="transmark"></span>
        max_price=0;
        for(int i=0;i < n;i++){
            scanf("%d",&value[i]);
            if(value[i] > max_price){
                mp=i;
                max_price=value[i];
            }
        }
        value[mp]=0;    // 最大单价的隔离出来
        scanf("%d",&money);
        if (money-5 >= 0) money-=5;    //卡上要保留5元钱,最低消费额为5元
        else{
            printf("%d\n",money);
            continue;
        }
        memset(F,0,sizeof(F));
        for(int i=0;i < n;i++){
            int min=max(value[i],money-sum(i,n));    //总价值减去,后面所有物品的总价值,一个常数的优化
                for(int j=money;j >= min;j--)     //注意这里是大于等于
                F[j]=max(F[j],F[j-value[i]]+value[i]);    //注意这里是当前背包容量j减去花费容量
        }
        printf("%d\n",money+5-F[money]-max_price);
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值