bb
untergehen · · 题解
本题解复杂度是
首先显然最后
我们背包统计出前后缀
-
\exist i, b_i\geq k^{\frac13}
此时枚举
- otherwise
我们断言,直接枚举相邻的前后缀 dp 合并是对的。复杂度
若存在
因为要求,蓝色部分乘积小于等于
综上该做法以
#include<bits/stdc++.h>
#define N 105
#define hV 50005
using namespace std;
namespace shan{
const double inf=1e18;
int n,k,a[N];
double pre[N][hV],suf[N][hV];
double ls[hV];
signed main(){
cin>>n>>k;
const int V=pow(k,0.666666)+1;
for(int i=0;i<=n+1;i++)
for(int j=0;j<=V+1;j++)
pre[i][j]=suf[i][j]=-inf;
pre[0][1]=suf[n+1][1]=0;
for(int i=1;i<=n;i++){
cin>>a[i];
for(int j=1;j<=min(V,a[i]);j++){
double me=log(a[i]/j);
for(int k=1;k*j<=5e4;k++)
pre[i][j*k]=max(pre[i][j*k],pre[i-1][k]+me);
}
}
for(int i=n;i>=1;i--){
for(int j=1;j<=min(V,a[i]);j++){
double me=log(a[i]/j);
for(int k=1;k*j<=V;k++)
suf[i][j*k]=max(suf[i][j*k],suf[i+1][k]+me);
}
}
double ans=-inf;
for(int j=k;j<=V;j++)ans=max(ans,suf[1][j]);
for(int i=1;i<=n;i++){
for(int j=1;j<=V+1;j++)ls[j]=-inf;
for(int j=1;j<=V;j++)
for(int k=1;k*j<=V;k++)
ls[j*k]=max(ls[j*k],pre[i-1][j]+suf[i+1][k]);
for(int j=V;j>=1;j--)
ls[j]=max(ls[j],ls[j+1]);
for(int l=1,r=0;l<=a[i];l=r+1){
int val=a[i]/l;
r=a[i]/val;
int need=(k+r-1)/r;
if(need<=V)
ans=max(ans,log(val)+ls[need]);
}
}
for(int i=1;i<=n;i++){
for(int j=V;j>=1;j--)
suf[i+1][j]=max(suf[i+1][j],suf[i+1][j+1]);
for(int j=1;j<=V;j++){
int need=(k+j-1)/j;
if(need<=V)
ans=max(ans,pre[i][j]+suf[i+1][need]);
}
}
ans+=log(k);
for(int i=1;i<=n;i++)ans-=log(a[i]);
cout<<fixed<<setprecision(20)<<exp(ans);
return 0;
}
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);
shan::main();
return 0;
}
有趣的知识:发现答案是乘积形式,可以取