饭卡 hdu2546(01背包)

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

分析:现要求你买过东西后卡上余额最少,而卡上余额只要大于等于5,那么一定可以购买成功,那么我们直接想法是要用这5元去买最贵的东西,(但是当卡上余额不足5元时,那么此时余额就是最小值了)。我们可以让余额先减去5,然后用剩下的钱进行背包,看最多还可以消费多少钱。状态方程为:dp[j]=max(dp[j], dp[j-a[i]]+a[i]),dp[j]表示的是买前i件商品,预算为j时的最大花销。

#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL;
#define maxn 1100
int dp[maxn], a[maxn];

int main()
{
    int n, sum;

    while(scanf("%d", &n), n)
    {
        for(int i=0; i<n; i++)
            scanf("%d", &a[i]);

        scanf("%d", &sum);

        if(sum<5)
        {
            printf("%d
", sum);
            continue;
        }

        sum -= 5;

        sort(a, a+n);
        memset(dp, 0, sizeof(dp));

        for(int i=0; i<n-1; i++)
        {
            for(int j=sum; j>=a[i]; j--)
            {
                dp[j] = max(dp[j-a[i]]+a[i], dp[j]);
            }
        }

        printf("%d
", sum+5-dp[sum]-a[n-1]);

    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/daydayupacm/p/5731713.html