51nod 1450 闯关游戏

首先肯定要先把所有的关卡打通后去找两星几率最大的关卡刷星(论打游戏经验的重要性)。

所以从两星几率小的关打起,记录当前拿到x个星星的几率和当前走过的期望步数,如果发现剩下的关必须全两星,就直接计算答案。

因为期望的线性,所以直接加起来不会有什么问题。

#include<bits/stdc++.h>
#define double long double
using namespace std;
const int N = 4005;
int n,m;
double x[N],y[N];
int p[N];
bool cmp(int xx,int xy)
{
	return y[xx]<y[xy];
}
double b[N];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%Lf%Lf",&x[i],&y[i]);
		x[i]/=1000;y[i]/=1000;
	}
	for(int i=1;i<=n;i++)p[i]=i;
	sort(p+1,p+n+1,cmp);
	b[0]=1;
	double ans=0;
	double now=1;
	for(int i=1;i<=n;i++)
	{
		int t=p[i];
		if(m-(n-i+1)*2>=i-1)
		{
			double tmp=0;
			for(int j=i;j<=n;j++)
			{
				tmp+=1/y[p[j]];
			}
			ans+=b[m-(n-i+1)*2]*tmp;
			now-=b[m-(n-i+1)*2];
			b[m-(n-i+1)*2]=0;
		}
		ans+=now/(x[t]+y[t]);
		for(int j=2*n;j>=0;j--)
		{
			b[j]=0;
			if(j>=1)b[j]=b[j-1]*x[t]/(x[t]+y[t]);
			if(j>=2)b[j]+=b[j-2]*y[t]/(x[t]+y[t]);
		}
	}
	printf("%.10Lf\n",ans);
	return 0;
}

  

posted @ 2017-06-18 21:08  SD_le  阅读(256)  评论(0编辑  收藏  举报
重置按钮