题目链接: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; }