POJ 1276

多重背包问题。

状态转移方程:

f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]}

复杂度是O(V*Σn[i])

#include <iostream>
#include <cstring>
using namespace std;

inline int Max(int a, int b);
int table[100001];
int n[1001], D[1001];

int main()
{
    int C, cash, N, flag;
    int i, j, k;

    while(cin >> cash)
    {
        flag = 1;
        memset(table,0,sizeof(table));
        cin >> N;
        for(i=0; i<N; i++)
        {
            cin >> n[i] >> D[i];
            if(D[i] <= cash)
                flag = 0;
        }

        if(cash == 0 || N == 0 || flag == 1)
        {
            cout << 0 << endl;
        }
        else
        {
            for(i=0; i<N; i++)
            {
                for(j=1; j<=n[i]; j*=2)
                {
                    for(k=cash; k>=1; k--)
                    {
                        if(j*D[i] <= k)
                            table[k] = Max(table[k], table[k-j*D[i]]+j*D[i]);
                    }
                    n[i] -= j;
                }
                if(n[i] != 0)
                {
                    for(k=cash; k>=1; k--)
                    {
                        if(n[i]*D[i] <= k)
                            table[k] = Max(table[k], table[k-n[i]*D[i]]+n[i]*D[i]);
                    }
                }
            }
            cout << table[cash] << endl;
        }
    }
    return 0;
}

inline int Max(int a, int b)
{
    if(a > b)
        return a;
    else
        return b;
}


你可能感兴趣的:(c,table)