zoukankan      html  css  js  c++  java
  • uva10417 概率DP

    这题 to[i][j] 为第i个人送j这个礼物的概率 我们用13进制进行压缩这个留下的的礼物的个数,这样我们将dp[i][k]表示为当第i个人放完礼物后得到的状态为k时的概率,那么通过记忆化搜索我们就得到了我们想要的状态概率即 dp[i][k]+={dp[i+1][k-aj]*to[i][aj]},好那么现在如果我去拿第一个礼物我正确的概率,我们 可以先知道好朋友放第一个的概率为

    假设S为最初礼物的状态

    pop=dp[1][S-a1]*to[0][1]/dp[0][S],这个是好朋友送了第一个礼物的概率,那么现在对于第一种礼物他有digit【0】个我们需要有1/digit[0]的概率去得到这个礼物,以此类推去得到第1个第2个等等。。。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    const int maxn=5;
    const int MAXM=13*13*13*13*13+5;
    int gift[maxn],n;
    double dp[13][MAXM],to[13][maxn];
    bool vis[13][MAXM];
    int A[maxn];
    double dfs(int loc, int G){
        if(vis[loc][G]) return dp[loc][G];
        int K=G;
        for(int i=4; i>=0; --i)
        {
             A[i] = K%13 ; K /= 13 ;
        }
        double ans=0;
        for(int i=0; i<5; ++i)
        if( A[i] ){
               A[ i ]--;
               K = 0;
               for( int j = 0 ; j<5 ; ++ j )
                 K = K * 13 + A[ j ] ;
              ans+=dfs( loc + 1 , K ) * to[ loc ][ i ] ;
              A[i]++;
        }
        vis[loc][G]=true;
        return dp[loc][G]=ans;
    }
    int main()
    {
       int cas;
       scanf("%d",&cas);
       while( cas -- ){
           scanf("%d",&n);
           for(int i=0; i<5; ++i)
            scanf("%d",&gift[i]);
           for(int i=0; i<n; ++i)
            for(int j=0; j<5; ++ j)
               scanf("%lf",&to[i][j]);
           memset(dp,0,sizeof(dp));
           memset(vis,false,sizeof(vis));
          vis[n][0]=1;
          dp[n][0]=1;
          int k=0;
          for(int i=0;i<5; ++i ){
               k=k*13+gift[i];
          }
          double res=dfs(0,k);
          int  ans=1;
          double pans=-1;
          for(int i=0; i<5; ++i)if(gift[i]){
              gift[i]--;
              k=0;
              for(int j=0; j<5; ++j)
                k=k*13+gift[j];
                gift[i]++;
              double a=dp[1][k]*to[0][i]/gift[i]/res;
              if(a>pans){
                 ans=i+1; pans=a;
              }
          }
          printf("%d %.3lf
    ",ans,pans);
       }
        return 0;
    }
    View Code
  • 相关阅读:
    telnet发邮件
    怎样接收电子邮件(POP3协议简介)(转载,写的很简洁)
    总结:string,char*,CString,int,WCHAR*之间的相互转换:
    文件查找
    SOAP消息机制简介
    jQuery 万能的选择器 NO.1
    数据库通用操作类
    jQuery (三) 管理jQuery包装集
    WebService Learning
    使用JQuery读取XML文件数据
  • 原文地址:https://www.cnblogs.com/Opaser/p/4148418.html
Copyright © 2011-2022 走看看