1. 程式人生 > >[poj2151]Check the difficulty of problems概率dp

[poj2151]Check the difficulty of problems概率dp

ems pan check tdi 乘法 icu amp bsp 反向

解題關鍵:主要就是概率的推導以及至少的轉化,至少的轉化是需要有前提條件的。

轉移方程:$dp[i][j][k] = dp[i][j - 1][k - 1]*p + dp[i][j - 1][k]*(1 - p)$ 其中$dp[i][j][k]$表示第$i$個人前j題恰好ac了$k$題.然後用前綴和處理一下最後的結果。

每隊至少AC一題 反向考慮,用1-每隊沒A題的概率,再用乘法原理結合一下。

冠軍隊至少AC$n-1$題,也就是存在一支隊伍AC數>=n-1,依然反向考慮,不過是在每隊AC至少一題的條件下,從而求出每隊AC數>=1,<n-1,再用前面的概率減去此概率即可。

 1
#include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 using namespace std; 8 typedef long long ll; 9 double p[1002][32],dp[1002][32][32],s[1002][32]; 10 int main(){ 11 int m,t,n; 12
ios::sync_with_stdio(0); 13 while(cin>>m>>t>>n&&(n||m||t)){ 14 for(int i=1;i<=t;i++){ 15 for(int j=1;j<=m;j++){ 16 cin>>p[i][j]; 17 } 18 } 19 20 for(int i=1;i<=t;i++){ 21
dp[i][0][0]=1; 22 for(int j=1;j<=m;j++){ 23 dp[i][j][0]=dp[i][j-1][0]*(1-p[i][j]);//類似楊輝三角的推法,註意按照怎樣的順序才能推出全部 24 } 25 } 26 27 for(int i=1;i<=t;i++){ 28 for(int j=1;j<=m;j++){ 29 for(int k=1;k<=j;k++){//註意控制變量範圍,保證有意義 30 dp[i][j][k]=dp[i][j-1][k-1]*p[i][j]+dp[i][j-1][k]*(1-p[i][j]); 31 } 32 } 33 } 34 for(int i=1;i<=t;i++){ 35 for(int j=0;j<=m;j++){ 36 s[i][j]=s[i][j-1]+dp[i][m][j]; 37 } 38 } 39 40 double ans1=1.0,ans2=1.0,t1; 41 for(int i=1;i<=t;i++) t1=1-s[i][0],ans1*=t1; 42 for(int i=1;i<=t;i++) t1=s[i][n-1]-s[i][0],ans2*=t1; 43 printf("%.3f\n",ans1-ans2); 44 45 46 47 } 48 }

[poj2151]Check the difficulty of problems概率dp