依托的做法,但是居然能过
RedLycoris · · 题解
考虑到最多只会有一个
- 没有任何一个
b_i \geq \sqrt{k} 。
那么我们可以考虑类似 meet-in-the-middle 的做法。
令
则我们这种情况下的最好答案就是枚举一个中间断点
此时我们需要证明,在所有选择的
不妨设一个
我们贪心的考虑,如果
此时第二维就需要开到一个
综上,该部分复杂度为
- 存在恰好一个
b_i \geq \sqrt{k} 。
那么我们可以直接枚举这个
然后我们枚举除了
该部分复杂度为
综上,总复杂度为 不知道为什么但只跑了 1.5s 通过此题。
#include<bits/stdc++.h>
using namespace std;
const int B=177830;
const int B2=6600;
int n,w,a[103];
double f[103][B+3],g[103][B+3],ans;
vector<int>v;
double h[B2+3];
int main(){
cin>>n>>w;
for(int i=1;i<=n;i++)
cin>>a[i];
f[0][1]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=B;j++)
for(int k=1;k<=B/j;k++)
f[i][j*k]=max(f[i][j*k],f[i-1][j]*(1.0*(a[i]/k)/a[i]));
for(int j=B;j>0;j--)
f[i][j]=max(f[i][j],f[i][j+1]);
}
g[n+1][1]=1;
for(int i=n;i;i--){
for(int j=1;j<=B;j++)
for(int k=1;j*k<=B;k++)
g[i][j*k]=max(g[i][j*k],g[i+1][j]*(1.0*(a[i]/k))/a[i]);
for(int j=B;j>0;j--)
g[i][j]=max(g[i][j],g[i][j+1]);
}
for(int i=0;i<=n;++i)for(int j=1;j<=B;++j)
if((w+j-1)/j<=B)ans=max(ans,f[i][j]*g[i+1][(w+j-1)/j]);
for(int i=1;i<=n;++i){
if(1){
for(int j=1;j<=B2;++j)h[j]=0;
for(int j=1;j<=B2;++j)
for(int k=1;k*j<=B2;++k)
h[j*k]=max(h[j*k],f[i-1][j]*g[i+1][k]);
for(int j=B2;j;--j)h[j]=max(h[j],h[j+1]);
for(int j=1;j<=B2;++j){
int ee=(w+j-1)/j;ee=max(ee,1);
if(ee>a[i])continue;
int e2=a[i]/ee;
ans=max(ans,1.0*e2/(1.0*a[i])*h[j]);
}
}
}
cout<<fixed<<setprecision(15)<<ans*w<<'\n';
}