C - Make Them Equal
#include<iostream>
#include<cstring>
using namespace std;
const int N=1010;
int ans[N][40010],c[N],b[N],a[N];
int main()
{
int t ;
cin>>t;
for(int i=1;i<=1000;i++)a[i]=1010;
a[1]=0;
for(int i=1;i<=1010;i++)
{
for(int j=i;j>=1;j--)
{
int x=i+i/j;
if(x<=1000)a[x]=min(a[x],a[i]+1);
}
}
while(t--)
{
int n,m;
cin>>n>>m;
m = min(m, n * 13);
for(int i=1;i<=n;i++)cin>>b[i],b[i] = a[b[i]];
for(int i=1;i<=n;i++)cin>>c[i];
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
ans[i][j]=ans[i-1][j];
if(j >= b[i]){
ans[i][j]=max(ans[i-1][j-b[i]]+c[i],ans[i][j]);
}
}
}
cout<<ans[n][m]<<endl;
}
return 0;
}
CF
先模拟出1变为x所需的最小次数,在转化为01背包问题
难点是如何求出1变为x的最小次数,在队里大哥的指导下,终于明白了,不能强硬的去求次数。
而是看一个数可以转化为哪些数,次数一次一次的加,这样就变得简单了。

