poj 2151Check the difficulty of problems<概率DP>
链接:http://poj.org/problem?id=2151
题意:一场比赛有 T 支队伍,共 M 道题, 给出每支队伍能解出各题的概率~
求 :冠军至少做出 N 题且每队至少做出一题的概率~
思路:设dp[i][j][k] 为 第 i 队 在前 j 题共解出 k 题的概率~
那么 dp[i][j][k]=dp[i][j-1][k-1]*p[i][j-1] + dp[i][j-1][k]*(1-p[i][j-1]) ~
s[i][0] 为 第 i 队至多解出N-1题的概率,s[i][1] 为第 i 队至少解出一题的概率~
那么就可以解出来了~
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int M, T, N; 6 double dp[1005][35][35], s[1005][2], p[1005][35]; 7 int main( ) 8 { 9 while(scanf("%d%d%d", &M, &T, &N)!= EOF, M+N+T){ 10 for( int i=0; i<T; ++ i ){ 11 for( int j=0; j<M; ++ j ){ 12 scanf("%lf", &p[i][j]); 13 } 14 } 15 memset(dp, 0, sizeof dp); 16 memset(s, 0, sizeof s); 17 double p1=1,p2=1; 18 for( int i=0; i<T; ++ i ){ 19 dp[i][0][0]=1; 20 for( int j=1; j<=M; ++ j ){ 21 for( int k=0; k<=j; ++ k ){ 22 dp[i][j][k]=dp[i][j-1][k-1]*p[i][j-1]+dp[i][j-1][k]*(1-p[i][j-1]); 23 if(j==M && k>0){ 24 s[i][1]+=dp[i][j][k]; 25 26 if(k<N){ 27 s[i][0]+=dp[i][j][k]; 28 } 29 } 30 } 31 } 32 33 p1*=s[i][1]; 34 p2*=s[i][0]; 35 } 36 printf("%.3f\n", p1-p2); 37 } 38 return 0; 39 }