POJ 2151 概率DP

主要的子问题是每一个队伍有一个做出题目的概率,求做出k个题目的概率。简单的简单的组合数DP。想清楚即可。

   1:  #include <iostream>
   2:  #include <cstdio>
   3:  #include <cstring>
   4:  using namespace std;
   5:   
   6:  double dp[35][35];
   7:  double p[1005][35];
   8:  int main()
   9:  {
  10:  //    freopen("1.txt","r",stdin);
  11:      int M,T,N;
  12:      while(cin>>M>>T>>N && M!=0)
  13:      {
  14:          memset(p, 0, sizeof(p));
  15:          memset(dp, 0, sizeof(dp));
  16:          for(int i=0; i<T; i++)
  17:          {
  18:              for(int j=0; j<M; j++)
  19:                  cin>>p[i][j];
  20:          }
  21:          double ans = 1.0;
  22:          for(int i=0; i<T; i++)
  23:          {
  24:   
  25:              double ret = 1.0f;
  26:              for(int j=0; j<M; j++)
  27:                  ret *= (1-p[i][j]);
  28:              ret  = 1 - ret;
  29:              ans *= ret;
  30:          }
  31:          double ant = 1.0f;
  32:          for(int i=0; i<T; i++)
  33:          {
  34:              // first i solved num is j
  35:              memset(dp, 0, sizeof(dp));
  36:              dp[1][0] = 1- p[i][0];
  37:              dp[1][1] = p[i][0];
  38:              for(int j=2; j<=M; j++) dp[j][0] = dp[j-1][0] * (1 - p[i][j-1]);
  39:              for(int j=2; j<= M; j++)
  40:              {
  41:                  for(int k = 1; k<=j; k++)
  42:                  {
  43:                      dp[j][k] = dp[j-1][k-1]*(p[i][j-1])+ dp[j-1][k]*(1 - p[i][j-1]);
  44:                  }
  45:              }
  46:              double sum = 0.0f;
  47:              for(int i=1; i<N; i++)
  48:                  sum += dp[M][i];
  49:              ant *= sum;
  50:          }
  51:          printf("%.3f\n", ans - ant);
  52:      }
  53:      return 0;
  54:  }

你可能感兴趣的:(poj)