01背包变化3

来源:互联网 发布:java实现公告管理系统 编辑:程序博客网 时间:2024/04/29 20:34

题目:hdu2546

题意:电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

解答:如果m<5直接输出余额。其他情况,先找出最大的最后减,然后m-=5,然后就转化成01背包问题了。

#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<cstdio>using namespace std;const int MAXN = 1010;int a[MAXN];int dp[MAXN];int main(){    int m,n;    while(~scanf("%d",&n))    {        if(n == 0)            break;        memset(dp,0,sizeof(dp));        int Max = 0,f;        for(int i = 0;i < n;i++)        {            scanf("%d",&a[i]);            if(a[i] > Max)                {                    Max= a[i];                    f = i;                }        }        scanf("%d",&m);        int ans;        if(m < 5)            ans = m;        else        {            m-=5;            for(int i = 0;i < n;i++)                {                    if(i == f)                        continue;                    for(int j = m;j>=0;j--)                    {                        if(j >= a[i])                            dp[j] = max(dp[j],dp[j-a[i]]+a[i]);                    }                }            ans = m + 5 - (dp[m] + Max);        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击