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

时间:2022-04-25 05:13:07

题意:已知昨天天气与今天天气状况的概率关系(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

 #include<stdio.h>
#include<string.h>
#include<math.h>
char yezi[][]= {"Dry","Dryish","Damp","Soggy"};
char wea[][]= {"Sunny","Cloudy","Rainy"};
double yeP[][]= {0.6,0.2,0.15,0.05,
0.25,0.3,0.2,0.25,
0.05,0.10,0.35,0.50
};
double weaP[][]= {0.5,0.375,0.125,
0.25,0.125,0.625,
0.25,0.375,0.375
};
double init[]= {0.63,0.17,0.2};
double dp[][],pre[][];
int n;
double maxp;
int Pos[];
void solve()
{
for(int i=; i<; i++)
{
dp[][i]=log(init[i])+log(yeP[i][Pos[]]);
//第1天天气为i的概率=初始的天气为i的概率*(第一天叶子为Pos[1]的的状态下天气为i的概率)
}
for(int i=; i<=n; i++) //
{
for(int j=; j<; j++) //天气
{
double maxp=-1e8;
int pos=;//记录天气
for(int k=; k<; k++) //第i-1天天气为k
{
double temp=dp[i-][k]+log(weaP[k][j])+log(yeP[j][Pos[i]]);
//昨天天气为k的概率*昨天天气为k今天天气为j的概率*叶子状态为Pos[i]时天气为j的概率
if(temp>maxp)
{
maxp=temp;
pos=k;//记录最有可能的天气状况为k
}
}
dp[i][j]=maxp;//第i天天气状况为j的概率
pre[i][j]=pos; //表示第i天天气最可能为j的前一天天气
}
}
}
int main()
{
int k=;
int T;
char yeC[];
scanf("%d",&T);
while(T--)
{
k++;
printf("Case #%d:\n",k);
scanf("%d",&n);
for(int i=; i<=n; i++)
{
scanf("%s",yeC);
for(int j=; j<; j++)
if(strcmp(yeC,yezi[j])==)
{
Pos[i]=j;
break;
}
}
solve();
double maxp=-1e8;
int ans[];
for(int i=; i<; i++)//第n天最有可能的天气
if(dp[n][i]>maxp)
{
maxp=dp[n][i];
ans[n]=i;
}
for(int i=n-;i>=;i--)
ans[i]=pre[i+][ans[i+]]; //由最后一天往前找每天的天气状况记录在ans 中
for(int i=;i<=n;i++)
printf("%s\n",wea[ans[i]]);
}
return ;
}

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

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

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