POJ1787 完全背包 xingxing在努力

  这道题的意思是给你1 5 10 25 的硬币c1 c2 c3 c4枚, 求出一个方案使硬币个数最多, 且恰好是p..给完全背包加几个状态即可。。代码如下:

  WA点: 可能看完动漫时间有点晚记得把题目终止输入条件判错了 2:used[j-w[i]]<num[i]写错成used[j-w[i]]+1<num[i],罪过罪过:

  

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 10000 + 100;
const int inf = 0x3f3f3f3f;
int f[maxn], pre[maxn], used[maxn];  //f表示组成j的时候最多有几个硬币 pre表示前继  used表示为j时同类为多少个
int p, num[4];
int w[] = {1, 5, 10, 25};

int main()
{
    while(scanf("%d%d%d%d%d", &p, &num[0], &num[1], &num[2], &num[3])==5)
    {
        if(!(p||num[0]||num[1]||num[2]||num[3]))    break;
        for(int i=0; i<=p; i++) f[i] = -inf;
        //memset(pre, 0, sizeof(pre));
        f[0] = 0;
        pre[0] = -1;
        for(int i=0; i<4; i++)
        {
            memset(used, 0, sizeof(used));
            for(int j=w[i]; j<=p; j++)
                if(f[j-w[i]]+1>f[j] && f[j-w[i]]>=0 && used[j-w[i]]<num[i])
                {
                    f[j] = f[j-w[i]] + 1;
                    used[j] = used[j-w[i]] + 1;
                    pre[j] = j-w[i];
                }
        }
        int ans[30];
        memset(ans, 0, sizeof(ans));
        if(f[p] < 0) printf("Charlie cannot buy coffee.
");
        else 
        {
            int now = p;
            while(pre[now] != -1)
            {
                ans[now-pre[now]]++;
                now = pre[now];
            }
            printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.
", ans[w[0]], ans[w[1]], ans[w[2]], ans[w[3]]);
        }
     }
    return 0;
}
原文地址:https://www.cnblogs.com/xingxing1024/p/5008929.html