码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2546 01背包

时间:2015-02-10 13:26:50      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:dp 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;
}


hdu 2546 01背包

标签:dp 01背包

原文地址:http://blog.csdn.net/jibancanyang/article/details/43701343

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!