题解:
d
p
[
i
]
dp[i]
dp[i]代表[i…n]这个区间分成多少段的期望值
我们从后面往前面扫描,当我们发现
i
−
j
i-j
i−j这个范围是满足的话,那么我们可以切分的点就存在
j
−
i
+
1
j-i+1
j−i+1个点。假设我们选择点k,k属于
[
i
,
j
]
[i,j]
[i,j]这个区间,那么我们这段的期望就是
1
/
l
e
n
1/len
1/len乘以(dp[k+1]+1),k属于
[
i
,
j
]
[i,j]
[i,j]。
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int a[N],sm[N];
double sum[N],dp[N];
signed main(){
int n,m,mx=0; cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",a+i),mx=max(mx,a[i]),sm[i]=sm[i-1]+a[i];
for(int i=1;i<=m;i++){
int x; scanf("%d",&x);
if(mx>x){
puts("YNOI is good OI!");
continue;
}
dp[n]=1,sum[n]=1,sum[n+1]=0;
for(int j=n,i=n-1;i>0;i--){
while(sm[j]-sm[i-1]>x) j--;
dp[i]=1.0/(j-i+1)*(sum[i+1]-sum[j+2])+1.0;
sum[i]=sum[i+1]+dp[i];
}
printf("%.2f\n",dp[1]);
}
}