欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

codevs 1060

程序员文章站 2022-03-09 19:17:21
...

题目大意:

  有2n张票,分别有A,B两类,求最后两个人拿到同种票的概率。n<=1250;


想想这题应该是组合啊。。但是到底是组合还是排列。。如果是组合, 概率为:1-两种票都取了n-1张的情况,但是这两种票都取了n-1张的情况怎么算,C(n,n-1)*c(n,n-1)/所有情况,而所有情况又怎么算,对于留下来的两张票只有两种情况,留下来的都是A,留下来的都是B,留下来的有A也有B,那么这么算。。概率总在50%浮动。。不知道哪里有问题,看起来又都是问题。


那么就有了递推的做法。。

思想很简单。假设F[i][j]表示前i个人选了A类票j张的情况,那么有:

(1) 当j=0时,即没有人选A类票,在前i-1个人的基础上,第i个人有两种选择,根据乘法原理,那么前i个人选A的概率 f[i][0]=f[i-1][0]*0.5;

(2) 当j=n时,即前i-1个人已经将A的n张票都买走,或前i-1个人买了此类票的n-1张,根据加法原理,前i个人选n的概率 f[i][n]=f[i-1][n]+f[i-1][n-1]*0.5------但是对于i<n的时候是不可能出现这种情况的呀,那么循环是不是需要在i=n时开始。。

(3) 当j!=0,j!=n时,f[i][j]=f[i-1][j-1]*0.5+f[i-1][j]*0.5-----类似。。LCS的思想有没有?

 

#include<cstdio>
#include<cstdlib>
using namespace std;

double f[3000][3000];

int main()
{
	int n;
	scanf("%d",&n);
	
	n=n/2;
	
	f[0][0]=1;
	
	for (int i=1;i<=2*n;i++) f[i][0]=f[i-1][0]*0.5;
	
	for (int i=1;i<=2*n;i++)
	  for (int j=1;j<=n;j++)
	  if (j==n) f[i][j]=f[i-1][j-1]*0.5+f[i-1][j];
	   else f[i][j]=(f[i-1][j]+f[i-1][j-1])*0.5;
    
    printf("%.4lf",f[2*n-2][n]*2);
}


被坑到了n没除以2。。。调了很久。。