Wannafly挑战赛3 珂学送分(期望dp)

科学送分

定义 d p [ i ] dp[i] dp[i] [ i , n ] 分 段 的 期 望 [i,n]分段的期望 [i,n]

那么 d p [ n ] = 1 dp[n]=1 dp[n]=1

对 于 确 定 的 i , 设 我 们 找 到 了 最 大 的 j 满 足 ∑ k = i j a k < x 对于确定的i,设我们找到了最大的j满足\sum\limits_{k=i}^{j}a_k<x i,jk=ijak<x

说 明 i 可 以 分 裂 到 [ i , j ] 上 的 任 意 一 个 点 去 , 那 么 有 j − i + 1 种 可 能 说明i可以分裂到[i,j]上的任意一个点去,那么有j-i+1种可能 i[i,j],ji+1

在 [ i , j ] 上 任 取 一 点 k 表 示 [ i , k ] 分 成 一 段 , 贡 献 期 望 是 1 j − i + 1 ∗ d p [ k + 1 ] 在[i,j]上任取一点k表示[i,k]分成一段,贡献期望是\frac{1}{j-i+1}*dp[k+1] [i,j]k[i,k],ji+11dp[k+1]

又 发 现 对 于 i 来 说 , 如 果 i 递 减 , j 也 递 减 , 所 以 可 以 维 护 后 缀 和 来 解 决 又发现对于i来说,如果i递减,j也递减,所以可以维护后缀和来解决 i,i,j,

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int a[maxn],pre[maxn],n,m,maxx;
double dp[maxn],su[maxn]; 
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i];
		pre[i]=pre[i-1]+a[i];
		maxx=max( maxx,a[i] );
	}
	while( m-- )
	{
		int x; cin >> x;
		if( maxx>x )
		{
			printf("YNOI is good OI!\n");
			continue;
		}
		su[n]=1,su[n+1]=0;
		dp[n]=1;
		int j=n;
		for(int i=n-1;i;i-- )
		{
			while( pre[j]-pre[i-1]>x )	j--;
			//i位置可以转移到[i,j] 
			dp[i]=1.0/( j-i+1 )*( su[i+1]-su[j+2] )+1.0;
			su[i]=su[i+1]+dp[i];
		}
		printf("%.2f\n",dp[1]);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值