POJ2151- Check the difficulty of problems(概率DP)

http://poj.org/problem?id=2151


给m,m道题

t,t个队伍

n,必须有队伍ac数超过n题



求  满足以下2个条件的概率

1、所有队伍至少过1题,

2、冠军队伍至少过n题



dp[i][j][k] 表示 第i只队伍做了前j道题,过了k题 

那么可以得到   dp[i][j][k]=dp[i][j-1][k-1]*(tm[i][j])+dp[i][j-1][k]*(1-tm[i][j]);  

当然要预处理一下dp[i][j][0]这些边界


得到dp[i][j][k]后,可以求 s[i][k] 表示第i队做了小于等于k题的概率 

//s[i][k]= dp[i][m][0]+dp[i][m][1]+...+ dp[i][m][k];
//=s[i][k-1]+dp[i][m][k];

同样要记得预处理边界 s[i][0]=dp[i][m][0];


那么最后 全部人至少作出1道题的概率是 p1=(1-s[ 1 ][0])*(1-s[ 2 ][0])*.....*(1-s[ t ][0])

全部人只做出(1至N-1)道题的概率p2= (s[1][N-1]-s[1][0])* ...*(s[i][N-1]-s[i][0])


p1-p2 得到的就是 所有人至少做出一道,并且有人至少做了n道的概率了。



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

double tm[1005][35];
int cun[1005];
double dp[1005][35][35];
double s[1005][35];
int main()
{
	int m,t,n;
	while(scanf("%d%d%d",&m,&t,&n)!=EOF)
	{
		int i,j,k;
		if (!m&&!t&&!n) break;
		memset(dp,0,sizeof(dp));
		memset(s,0,sizeof(s));
		memset(cun,0,sizeof(cun));
		for (i=1;i<=t;i++)
		{
			for (j=1;j<=m;j++)
			{
				scanf("%lf",&tm[i][j]);
				if (tm[i][j]>0) cun[i]++;
			}
		}
		int flag=0;
		for (i=1;i<=t;i++)
		{
			if (cun[i]>=n) flag=1;
			if (cun[i]==0){flag=0;break;}
		}
	 	if (!flag) {printf("0.000\n"); continue;} 
	//初始化
		
		for (i=1;i<=t;i++)
		{
			dp[i][0][0]=1;
			for (j=1;j<=m;j++)
			{
				
				dp[i][j][0]=dp[i][j-1][0] * (1-tm[i][j]);
				
			}
			s[i][0]=dp[i][m][0];
		}
		
		for (i=1;i<=t;i++)
		{
			for (j=1;j<=m;j++)
			{
				for (k=1;k<=j;k++)
				{
					dp[i][j][k]=dp[i][j-1][k-1]*(tm[i][j])+dp[i][j-1][k]*(1-tm[i][j]);
				}
			}
		}
		//s[i][k]第i队做了不超过k题的概率
		//s[i][k]= dp[i][m][0]+dp[i][m][1]+...+ dp[i][m][k];
		//=s[i][k-1]+dp[i][m][k];
		for (i=1;i<=t;i++)
		{	 
			for (j=1;j<=m;j++)
			{ 
				s[i][j]=s[i][j-1]+dp[i][m][j];
			} 
		}
		
		double p1=1;
		double p2=1;
		for (i=1;i<=t;i++)
		{
			p1*=(1-s[i][0]);
			p2*=s[i][n-1]-s[i][0];
		}
		
		printf("%.3lf\n",p1-p2);
	}
	return 0;
	
}



你可能感兴趣的:(POJ2151- Check the difficulty of problems(概率DP))