题目
问题描述
分析
可转化01背包,两点注意:
1.进行打表记录抵达每个
b
[
i
]
b[i]
b[i]的最优策略,否则超时,可以DP,可以搜索;
2.
k
=
m
i
n
(
k
,
s
u
m
)
k=min(k,sum)
k=min(k,sum),否则可能会有k过大的情况,导致时间的浪费。
代码
#include<bits/stdc++.h>
#define fir(i, a, b) for (int i = (a); i <= (b); i++)
#define rif(i, a, b) for (int i = (a); i >= (b); i--)
using namespace std;
typedef long long ll;
const int N=1005;
ll v[N],w[N],f[N],t[1000005],k,m,tt;
void init(){
f[1]=0;
fir(i,2,N-1){
f[i]=N;
}
fir(i,1,N-1){
fir(x,1,i){
int j=i+i/x;
if(j<N)f[j]=min(f[j],f[i]+1);
}
}
}
int main(){
init();
cin>>tt;
while(tt--){
sum=0;
memset(t,0,sizeof t);
cin>>m>>k;
fir(i,1,m){
cin>>v[i];
v[i]=f[v[i]];
sum+=v[i];
}
fir(i,1,m){
cin>>w[i];
}
k=min(k,sum);
fir(i,1,m){
rif(j,k-v[i],0){
t[j+v[i]]=max(t[j+v[i]],t[j]+w[i]);
}
}
cout<<t[k]<<endl;
}
}