#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 1100;
int val[M],vol[M],dp[M][M]; // dp[i][j][k] 前i件物品装进体积J的第k优解 dp[i][j][k] = 从前一个状态中 2k(可能有重复)选不相同k个依次存入 dp[i][j][k] k=1~k dp][i-1][j][k],dp[i-1][j-vol[i]][k]
int main()
{
int t;
cin>>t;
while(t--)
{
int n,v,k;
cin>>n>>v>>k;
for(int i=1;i<=n;i++)
{
cin>>val[i];
}
for(int i=1;i<=n;i++)
{
cin>>vol[i];
}
memset(dp,0,sizeof(dp)); //前0件为0 没有k优解也为0
for(int i=1;i<=n;i++)
{
for(int j=v;j>=vol[i];j--) //逆推
{
int res1[M],res2[M]; // 保留前一个状态的k个解
for(int a=1;a<=k;a++)
{
res1[a]=dp[j][a];
res2[a]=dp[j-vol[i]][a]+val[i];
}
int x=1,y=1,z=1;
res1[k+1]=res2[k+1]=-1; //
while(z<=k&&(x<=k||y<=k))
{
if(res1[x]>res2[y])
{
dp[j][z]=res1[x];
x++;
}
else
{
dp[j][z]=res2[y];
y++;
}
if(dp[j][z]!=dp[j][z-1]) //从大到小 相等的在相邻
{
z++;
}
}
}
}
cout<<dp[v][k]<<endl;
}
return 0;
}
hdu 2639 01背包-K优解
最新推荐文章于 2021-05-02 14:27:04 发布