多重背包问题。
状态转移方程:
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;
}