天天看点

HDU 2546 饭卡

题目链接:​​传送门​​ 题面:

Problem Description

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。

某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

Input

多组数据。对于每组数据:

第一行为正整数n,表示菜的数量。n<=1000。

第二行包括n个正整数,表示每种菜的价格。价格不超过50。

第三行包括一个正整数m,表示卡上的余额。m<=1000。

n=0表示数据结束。

Output

对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。

Sample Input

1

50

5

10

1 2 3 2 1 1 2 3 2 1

50

Sample Output

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <vector>
#include <iomanip>
#define
#define
#define

using namespace std;
int n, w[A], V, ans, f[A];

int main() {
    while (cin >> n) {
        if (!n) return 0;
        memset(f, 0, sizeof f);
        for (int i = 1; i <= n; i++) cin >> w[i];
        sort (w + 1, w + n + 1);
        cin >> V;
        if (V < 5) {
            cout << V << endl;
            continue;
        }
        V -= 5;
        for (int i = 1; i < n; i++)
          for (int j = V; j >= w[i]; j--)
            f[j] = max(f[j], f[j - w[i]] + w[i]);
        cout << V + 5 - f[V] - w[n] << endl;
    }
}