(背包其实万变不离其宗)
(普通的转移时(v表示体积w表示价值))
[dp[i]=max(dp[i],dp[i-v]+w)
]
(现在情况稍微有点不同,我们需要保留dp[i]的前k优解,同样也保留了dp[i-v]的前k优解)
(可以这样简单的表示)
(其实总共可以从dp[i]的前k优解和dp[i-v]的前k优解转移过来,也就是从k+k中状态选前k优解转移)
(怎么实现的可以看代码)
#include <bits/stdc++.h>
using namespace std;
int f[5009][60],ans=0;
int k,v,n,vv[209],value[209];
int main()
{
for(int i=0;i<=5000;i++)
for(int j=0;j<=60;j++) f[i][j]=-999999999;
scanf("%d%d%d",&k,&v,&n);
for(int i=1;i<=n;i++) cin>>vv[i]>>value[i];//体积和价值
f[0][1]=0;
for(int i=1;i<=n;i++)
for(int j=v;j>=vv[i];j--)
{
int t1=1,t2=1,t[60],len=0;
while(t1+t2<=k+1)
{
if(f[j][t1]>f[j-vv[i]][t2]+value[i])
t[++len]=f[j][t1++];//选一种大的转移
else
t[++len]=f[j-vv[i]][t2++]+value[i];
}
for(int K=1;K<=k;K++) f[j][K]=t[K];
}
for(int i=1;i<=k;i++) ans+=f[v][i];
cout<<ans;
}