这是个多重背包问题,第二次我把它转化为01背包问题,结果TLE. 因为我把它转化为N*nk[i]张钞票,cash的最大值为100000,这种做法显然会超时。不过我的体会也挺深的,就是01背包的思想很重要,其他背包问题可以通过一定的方式转化为01背包问题,加上一定的优化,就能达成我们的目的。优化后的01背包的状态转移方程为:
for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
第三次重敲代码,我是用二进制思想来进行优化的。就是把nk[i]件物品分成2^0,2^1,、、、,2^(k-1),nk[i]-2^(k-1),这些项的和为nk[i],即可以通过这些来构成0~nk[i]期间的任一一种情况。这是一个很好的优化,时间复杂度降到(V*Σlog n[i]),对于这题来说已经够优化了。我提交的结果时间是76MS.多重背包转化后的伪代码如下:
k = 1;
while(k <= nk[i])
{
zeroone(); / / 这是01背包;
nk[i] -= k;
k *=2;
}
k = nk[i];
zeroone();
pku1276的代码
code:
#include<string.h>
#include<stdio.h>
#define n 100005
int max(int a, int b)
{
return a > b ? a : b;
}