POJ 2151(Check the difficulty of problems)

14 篇文章 0 订阅

题意:有 M 个问题,T 只队伍, 给定 p[ i ][ j ] 表示第 i 只队伍解决第 j 个问题的概率, 求所有队伍解决至少一个问题并且冠军(解决问题最多的队伍)解题数 >= N 的概率

 

分析:设 dp[ i ][ j ][ k ] 表示 第 i 只队伍在前 j 个问题里解决 k 个问题的概率, 

比较容易可以推出转移方程 dp[ i ][ j ][ k ] = dp[ i ][ j-1 ][ k-1 ] * p[ i ][ j ] + dp[ i ][ j-1 ][ k ] * (1 - p[ i ][ j ])

由题意 设 p1 为所有队伍解决至少一个问题的概率, p2 为所有队伍解决问题数皆处于 [ 1 , n-1 ] 的概率, 

则题解为 p1 - p2 。

p1  =   \prod_{i=1}^{T} (1-dp[i][M][0])

p2  =   \prod_{i=1}^{T}\sum_{k=1}^{n-1}(dp[ i ][ M ][ k ])

 

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int M = 35;

double dp[M][M],p[M];   

int m,tt,n;

int main()
{
	while(cin>>m>>tt>>n&&(m||tt||n))
	{
		double p1=1.0 , p2=1.0;
		for(int t=1;t<=tt;t++)  //滚动数组节省空间 
		{
		  memset(dp,0,sizeof(dp));
		  dp[0][0]=1.0;
		  
		  for(int i=1;i<=m;i++)
		  {
			cin>>p[i];
			for(int j=0;j<=i;j++)
			{
				if(j==0) dp[i][j]=dp[i-1][0]*(1-p[i]);
				else dp[i][j]=dp[i-1][j-1]*p[i]+dp[i-1][j]*(1-p[i]);
			}
		  }
		  
		  p1*=(1-dp[m][0]);
		  
		  double sum=0.0;
		  for(int i=1;i<n;i++)
		  {
		  	sum+=dp[m][i];
		  }
		  p2*=sum;
		  
	    }
	    printf("%.3f\n",p1-p2);
    }
	return 0;
} 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值