将我隐藏,成为星空中崭新的孤岛|

cc0000

园龄:5年1个月粉丝:14关注:5

[HNOI2015]亚瑟王

题面

首先可以知道的是,牌与牌之间的期望收益互相不影响,所以我们对每种牌分开进行计算。所以我们设出状态,fi,j 到第 i 种牌,已经过了 j 轮,第 i 种牌抽到的概率。

if(j) f[i][j]=(f[i-1][j-1]*(1.0-pow(1-a[i],r-j+1))+f[i][j]);
f[i][j]=(f[i-1][j]*pow(1-a[i],r-j)+f[i][j]);

第一行的意思是在后来的 rj+1 轮中必有一次选到的概率是 (1(1ai)rj+1)

第二行就是在后来的这些轮里一次都选不上,这时的概率是 (1ai)rj

最后的结果就是 (1(1ai)rj)×fi1,j×di

fi1,j 时没被开到,后来有 1(1ai)rj 的概率也开不到,那么当下被开到的概率就是乘积,再乘上收益就行。

#include <bits/stdc++.h>
using namespace std;
typedef double db;
const int maxn=320;
int T;
int n,r;
db a[maxn],f[maxn][maxn],ans;int d[maxn];
void clear()
{
	memset(f,0,sizeof(f)); ans=0;
}
int main()
{
	//freopen("p.in","r",stdin);
	scanf("%d",&T);
	while(T--)
	{
		clear();
		scanf("%d%d",&n,&r);
		for(int i=1;i<=n;i++)
		{
			scanf("%lf%d",&a[i],&d[i]);
		}
		f[0][0]=1;
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<=min(i,r);j++)
			{
				if(j) f[i][j]=(f[i-1][j-1]*(1.0-pow(1-a[i],r-j+1))+f[i][j]);
				f[i][j]=(f[i-1][j]*pow(1-a[i],r-j)+f[i][j]);
			}
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<min(i,r);j++)
				 ans+=d[i]*f[i-1][j]*(1.0-pow(1-a[i],r-j));
		}
		printf("%.10f\n",ans);
	}
}

本文作者:cc0000

本文链接:https://www.cnblogs.com/cc0000/p/16808153.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   cc0000  阅读(21)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起