HDU - 2546 饭卡(01背包)

来源:互联网 发布:阿国网络随笔说人性 编辑:程序博客网 时间:2024/05/16 07:32

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

解题思路;按照贪心的思想,菜的价格就要从小到达排,因为要以最小的钱(大于等于5)买最贵的菜,那样才会使余额达到最小

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 1010;const int INF = 0x3f3f3f3f;int n, m;int num[N];bool vis[N];bool cmp(const int &a, const int &b) {    return a < b;}void init() {    for (int i = 0; i < n; i++)        scanf("%d", &num[i]);    scanf("%d", &m);    sort(num, num + n, cmp);}void solve() {    if (m < 5) {        printf("%d\n", m);        return ;    }    memset(vis, 0, sizeof(vis));    vis[m] = true;    int ans = INF;    for (int i = 0; i < n; i++) {        for (int j = 5; j <= m; j++) {            if (vis[j]) {                if (j - num[i] >= 5) vis[j - num[i]] = true;                ans = min(j - num[i], ans);            }             else {                if (j + num[i] <= m && vis[j + num[i]]) vis[j] = true;            }        }    }    printf("%d\n", ans);}int main() {    while (scanf("%d", &n) != EOF && n) {        init();        solve();    }    return 0;}
0 0