• HDU 4865 Peter's Hobby(2014 多校联合第一场 E)(概率dp)


    题意:已知昨天天气与今天天气状况的概率关系(wePro),和今天天气状态和叶子湿度的概率关系(lePro)
    第一天为sunny 概率为 0.63,cloudy 概率 0.17,rainny 概率 0.2.
    给定n天的叶子湿度状态,求这n天最可能的天气情况

    分析:概率dp
    设 dp[i][j] 表示第i天天气为j的最大概率,
    pre[i][j]表示第i天天气最可能为j的前一天天气,
    dp[i][j]=max(dp[i-1][k]+log(wePro[k][j])+log(lePro[j][lePos[i]])) (k=0,1,2 表示昨天的天气)

    注:由于概率越乘越小,考虑精度原因,用log取对数
    log(a*b*c) = log a + log b +log c

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<math.h>
     4 char yezi[5][10]= {"Dry","Dryish","Damp","Soggy"};
     5 char wea[4][10]= {"Sunny","Cloudy","Rainy"};
     6 double yeP[3][4]= {0.6,0.2,0.15,0.05,
     7                    0.25,0.3,0.2,0.25,
     8                    0.05,0.10,0.35,0.50
     9                   };
    10 double weaP[3][3]= {0.5,0.375,0.125,
    11                     0.25,0.125,0.625,
    12                     0.25,0.375,0.375
    13                    };
    14 double init[3]= {0.63,0.17,0.2};
    15 double dp[51][3],pre[51][3];
    16 int n;
    17 double maxp;
    18 int Pos[51];
    19 void solve()
    20 {
    21     for(int i=0; i<3; i++)
    22     {
    23         dp[1][i]=log(init[i])+log(yeP[i][Pos[1]]);
    24                  //第1天天气为i的概率=初始的天气为i的概率*(第一天叶子为Pos[1]的的状态下天气为i的概率)
    25     }
    26     for(int i=2; i<=n; i++) //
    27     {
    28         for(int j=0; j<3; j++) //天气
    29         {
    30             double maxp=-1e8;
    31             int pos=0;//记录天气
    32             for(int k=0; k<3; k++) //第i-1天天气为k
    33             {
    34                 double temp=dp[i-1][k]+log(weaP[k][j])+log(yeP[j][Pos[i]]);
    35                 //昨天天气为k的概率*昨天天气为k今天天气为j的概率*叶子状态为Pos[i]时天气为j的概率
    36                 if(temp>maxp)
    37                 {
    38                     maxp=temp;
    39                     pos=k;//记录最有可能的天气状况为k
    40                 }
    41             }
    42             dp[i][j]=maxp;//第i天天气状况为j的概率
    43             pre[i][j]=pos; //表示第i天天气最可能为j的前一天天气
    44         }
    45     }
    46 }
    47 int main()
    48 {
    49     int k=0;
    50     int T;
    51     char yeC[10];
    52     scanf("%d",&T);
    53     while(T--)
    54     {
    55         k++;
    56         printf("Case #%d:
    ",k);
    57         scanf("%d",&n);
    58         for(int i=1; i<=n; i++)
    59         {
    60             scanf("%s",yeC);
    61             for(int j=0; j<4; j++)
    62                 if(strcmp(yeC,yezi[j])==0)
    63                 {
    64                     Pos[i]=j;
    65                     break;
    66                 }
    67         }
    68         solve();
    69         double maxp=-1e8;
    70         int ans[51];
    71         for(int i=0; i<3; i++)//第n天最有可能的天气
    72             if(dp[n][i]>maxp)
    73             {
    74                 maxp=dp[n][i];
    75                 ans[n]=i;
    76             }
    77          for(int i=n-1;i>=1;i--)
    78             ans[i]=pre[i+1][ans[i+1]];  //由最后一天往前找每天的天气状况记录在ans 中
    79         for(int i=1;i<=n;i++)
    80             printf("%s
    ",wea[ans[i]]);
    81     }
    82     return 0;
    83 }

    资料扩展:详情点此
    本题属于 隐马尔可夫模型
    马尔可夫模型:统计模型,每个状态只依赖于之前的状态

    马尔可夫模型可用马尔可夫过程描述
    我们就为上面的一阶马尔科夫过程定义了以下三个部分:
      状态:晴天、阴天和下雨
      初始向量:定义系统在时间为0的时候的状态的概率
      状态转移矩阵:每种天气转换的概率
      所有的能被这样描述的系统都是一个马尔科夫过程。

    隐马尔可夫模型 (Hidden Markov Model) 是一种统计模型,用来描述一个含有隐含未知参数的马尔可夫过程。
    包含隐藏状态 (如:天气状态)和 可观状态(如:叶子的湿度)
    可以观察到的状态序列和隐藏的状态序列是概率相关的

  • 相关阅读:
    js的异步运行机制
    Android NDK 安装与配置
    JNI与NDK的区别
    Android 开发手记一NDK编程实例
    android AIDL服务
    Android Service学习之AIDL, Parcelable和远程服务
    Android中JNI的使用方法
    Android之drawable state各个属性详解
    android中的Touch研究
    Android中的ListView点击时的背景颜色设置
  • 原文地址:https://www.cnblogs.com/PJQOOO/p/4642731.html
Copyright © 2020-2023  润新知