Make them Equal tj
简述题意
你有一个长度为 的数列 ,和两个长度为 的序列 。
定义一次操作为:确定 ,使得
如果 ,贡献加 。求最大贡献。
算法分析
DP。
先算出1到每个值进行操作的最小次数,记做 。
接着,对于每一问,将它的价值记做 ,需要用钱 。
背包便可。
代码实现
#include<bits/stdc++.h>
#define int long long
using namespace std;
int f[20000];
int w[10005],v[10005],dp[100005];
int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
signed main()
{
int T=read();
memset(f,127,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]+1,f[i+i/j]);//提前计算f(n)
}
while(T--)
{
int n=read(),k=read(),sum1=0,sum2=0;
for(int i=1;i<=n;i++)
{
int x=read();
w[i]=f[x];sum1+=f[x];
}
for(int i=1;i<=n;i++) v[i]=read(),sum2+=v[i];
if(sum1<=k)//不加上这个,离奇RE
{
cout<<sum2<<endl;
continue;
}
int ans=0;
memset(dp,0,sizeof(dp));
dp[0]=0;
for(int i=1;i<=n;i++)
for(int j=k;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
for(int i=0;i<=k;i++) ans=max(ans,dp[i]);
cout<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号