首页 > 其他分享 > [HNOI2015]亚瑟王

[HNOI2015]亚瑟王

时间:2022-10-19 23:14:49浏览次数:78  
标签:概率 int pow clear maxn HNOI2015 亚瑟王

题面

首先可以知道的是,牌与牌之间的期望收益互相不影响,所以我们对每种牌分开进行计算。所以我们设出状态,\(f_{i,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]);

第一行的意思是在后来的 \(r-j+1\) 轮中必有一次选到的概率是 \((1-(1-a_{i})^{r-j+1})\)。

第二行就是在后来的这些轮里一次都选不上,这时的概率是 \((1-a_i)^{r-j}\)。

最后的结果就是 \(\sum (1-(1-a_i)^{r-j})\times f_{i-1,j}\times d_i\)。

到 \(f_{i-1,j}\) 时没被开到,后来有 \(1-(1-a_i)^{r-j}\) 的概率也开不到,那么当下被开到的概率就是乘积,再乘上收益就行。

#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);
	}
}

标签:概率,int,pow,clear,maxn,HNOI2015,亚瑟王
From: https://www.cnblogs.com/cc0000/p/16808153.html

相关文章

  • P1930 [USACO3.3]亚瑟王的宫殿
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglongintr,c;intkx,ky;intMap[1001][1001];namespacebfs{constintdx[8]={1,1,2,2,-1,-1,-......