hdu 2546 饭卡(01背包)(变化了一小下)

来源:互联网 发布:windows错误报告 进程 编辑:程序博客网 时间:2024/05/17 02:24

hdu 2546 饭卡

分析

01背包的变种,题目就是说,有n种菜,饭卡剩m元,如何使饭卡剩的钱最少,当然有个限制,就是可以进行这次购买的前提是m要大于等于5元。
感觉自己思维还是太死了,就是因为这个大于5元的限制想了半天,其实可以想到,在还剩5元时,只要再买一次价钱最大的菜就可以了,那问题就转化为在有m-5元时,如何花最多的钱,也就是01背包问题。如果这样,就不用每次转换时考虑是不是大于5元了。要学会往熟悉的问题上转化。

问题

http://acm.hdu.edu.cn/showproblem.php?pid=2546

代码

#include <iostream>#include <cstring>#include <ctime>#include <fstream>#include <cstdlib>#include <algorithm>#include <set>#include <vector>using namespace std;int dp[1010];int dish[1010];int main(){    int n;    while(scanf("%d",&n)&&n!=0)    {        memset(dp,0,sizeof(dp));        for(int i=1; i<=n; i++)            scanf("%d",&dish[i]);        int money;        scanf("%d",&money);        if(money<5)        {            cout<<money<<endl;            continue;        }        sort(dish+1,dish+n+1,greater<int>());        int maxn=dish[1];        if(n==1)        {            cout<<money-dish[1]<<endl;            continue;        }        money-=5;        for(int i=2; i<=n; i++)            for(int j=money; j>=dish[i]; j--)                dp[j]=max(dp[j],dp[j-dish[i]]+dish[i]);        cout<<money-dp[money]-maxn+5<<endl;    }    return 0;}
0 0