饭卡 HDU - 2546

原题链接

考察:01背包

这道题懵逼半天,看了大佬的代码终于懂了点

思路:

      这道题是和购买顺序有关的,我们先拿出最贵的菜,同时余额拿出5元,在剩余的余额尽可能买总和贵的菜.买完最后余额拿出的5元再买最贵的菜,这就是正解了....

 

也因为这道题搞明白了点01背包的板子.f[i][j]表示在j余额条件下,前i个物品所能达到的最大价值.这道题如果设置f[i][j]==余额的话,表示的是在前i个菜,买前j余额在买后能达到的最小余额.属性值和j的含义重复给我搞懵了..果然还是太菜啊

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

 

posted @ 2021-02-01 18:08  acmloser  阅读(59)  评论(0编辑  收藏  举报