解
按照题意,容易想到用01背包做。
可以把
那么问题来了,如何求出把
我们可以递推求解。
我们设
memset(f,0x3f,sizeof(f));
f[1]=0;//初始化,1操作到1是0
for(int i=1;i<=1000;i++)
{
for(int j=1;j<=i;j++)//即为除数x
{
f[i+i/j]=min(f[i+i/j],f[i]+1);//把i修改成i+i/j,更新答案
}
}
那么,这样预处理出了结果。
下面是代码:
#include<bits/stdc++.h>
using namespace std;
int T,N,V,b[1001],w[1001],c[1001],f[2001],dp[1000001];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
memset(f,0x3f,sizeof(f));
f[1]=0;
for(int i=1;i<=1000;i++)
{
for(int j=1;j<=i;j++)
{
f[i+i/j]=min(f[i+i/j],f[i]+1);
}
}
cin>>T;
while(T--)
{
memset(dp,0,sizeof(dp));
cin>>N>>V;
for(int i=1;i<=N;i++)
{
cin>>b[i];
w[i]=f[b[i]];
}
for(int i=1;i<=N;i++)
{
cin>>c[i];
}
for(int i=1;i<=N;i++)
{
for(int j=V;j>=w[i];j--)
{
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
}
}
cout<<dp[V]<<"\n";
}
}