hdu 2546 饭卡 01背包

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546

一个01背包的小小变式

先贪心取一个最大值

然后剩下的用01背包做

最后减掉那个最大值

可能的坑点在于如果给出的钱数本身就小于5则需要直接输出

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <set>
#include <queue>
#include <vector>

using namespace std;

typedef long long ll;

const int maxn = 1010;

int w[maxn], c[maxn], f[maxn];
int ans;
int n, V;


void ZeroOnePack(int cost, int weight)
{
    for(int i = V; i >= cost; i--)
    {
        f[i] = max(f[i], f[i-cost] + weight);
        if(f[i] > ans)
            ans = f[i];
    }
}

int main()
{
    //freopen("in.txt", "r", stdin);

    while(scanf("%d", &n) == 1 && n != 0)
    {
        ans = 0;
        memset(f, 0, sizeof(f));

        int maxnum = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &w[i]);
            if(w[i] > maxnum)
                maxnum = w[i];
        }

        scanf("%d", &V);

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


        V -= 5;

        bool flag = true;
        for(int i = 0; i < n; i++)
        {
            if(flag && w[i] == maxnum)
            {
                flag = false;
                continue;
            }
            ZeroOnePack(w[i], w[i]);
        }

        printf("%d
", (V - ans) - maxnum + 5);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/dishu/p/4295563.html