标签:opened 概率 == include 解析 ems int ref 概率dp
http://poj.org/problem?id=2151
题意:
ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率
问 每队至少解出一题且冠军队至少解出N道题的概率。
分析:
解析:DP
设dp[i][j][k]表示第i个队在前j道题中解出k道的概率
则:
dp[i][j][k]=dp[i][j-1][k-1]*p[j][k]+dp[i][j-1][k]*(1-p[j][k]);
先初始化算出dp[i][0][0]和dp[i][j][0];
设s[i][k]表示第i队做出的题小于等于k的概率
则s[i][k]=dp[i][M][0]+dp[i][M][1]+``````+dp[i][M][k];
则每个队至少做出一道题概率为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[2][N-1]-s[2][0])*```(s[T][N-1]-s[T][0]);
最后的答案就是P1-P2
这题不容易啊 , dp的部分还好想啊,可是把答案转化为P1-P2这一步就是核心了,只能说TQL
#include<stdio.h> #include<string.h> double dp[1010][31][31],p[1010][31],S[1010][31]; int main() { int n,m,T; while(~scanf("%d%d%d",&m,&n,&T)){ if(m==0&&n==0&&T==0) break; memset(dp,0,sizeof(dp)); memset(S,0,sizeof(S)); for(int i=1 ; i<=n ; i++) for(int j=1 ; j<=m ; j++) scanf("%lf",&p[i][j]); //dp[i][j][k]:第i个队伍前j道题目完成了k个 for(int i=1 ; i<=n ; i++) {dp[i][0][0]=1; for(int j=1 ; j<=m ; j++) { dp[i][j][0]=dp[i][j-1][0]*(1-p[i][j]); } } for(int i=1 ; i<=n ; i++) { for(int j=1 ; j<=m ; j++) { for(int k=1 ; k<=j ; k++) { dp[i][j][k]=dp[i][j-1][k-1]*p[i][j] + dp[i][j-1][k]*(1-p[i][j]); } } } // S[i][M]:第i队伍完成M道题的概率 for(int i=1 ; i<=n ; i++) { S[i][0]=dp[i][m][0]; for(int j=1 ; j<=m ; j++) { S[i][j]=S[i][j-1]+dp[i][m][j]; } } double ans1=1; for(int i=1 ; i<=n ; i++) { ans1*=(1-S[i][0]); } double ans2=1; for(int i=1 ; i<=n ; i++) { ans2*=(S[i][T-1]-S[i][0]); } printf("%.3f\n",ans1-ans2); } }
POJ 2151 Check the difficulty of problems(概率DP)
标签:opened 概率 == include 解析 ems int ref 概率dp
原文地址:https://www.cnblogs.com/shuaihui520/p/11154651.html