HDU4865

来源:互联网 发布:js数组转为json字符串 编辑:程序博客网 时间:2024/05/17 23:09
意: 真难解释清楚,给你一个海藻的状态序列,让你找出一个最有可能的天气序列,前一天的天气能影响今天的天气,海藻的状态受天气的影响。
(从题目中应该是读不出他是怎样影响的,具体看下面的推荐的链接) 
思路: 这其实是隐马尔可夫模型(HMM)的一个应用,根据可观察状态的序列找到一个最可能的隐藏状态序列,
隐马尔可夫模型介绍见这里:点击打开链接 dp[i][j]表示第i天天气为j的概率,
dp[i][j]=dp[i-1][k]*wea[k][j]*lea[j][num[i]],记录路径,最后输出最有可能的路径,
根据最后一天的概率来看。 
#include<iostream>#include<cmath>//A了 #include <cstdio> #include <cstring> using namespace std;double aa[3][4]={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 bb[3][3]={0.5, 0.375, 0.125, 0.25, 0.125, 0.625, 0.25, 0.375, 0.375};int t,n;double dp[55][3];int pre[55][3];int ans[55];int ca;int lea[55]; int main(){for(int i=0;i<3;i++)for(int j=0;j<4;j++){aa[i][j]=log(aa[i][j]);}for(int i=0;i<3;i++)for(int j=0;j<3;j++){bb[i][j]=log(bb[i][j]);}while(cin>>t){if(t==0)break;while(t--){cin>>n;for(int i=0;i<n;i++){char s[22]; scanf("%s",s); if(strcmp(s,"Dry")==0) lea[i]=0; else if(strcmp(s,"Dryish")==0) lea[i]=1; //这里的方法挺不错的 else if(strcmp(s,"Damp")==0) lea[i]=2; else lea[i]=3;}dp[0][0]=log(0.63)+aa[0][lea[0]];dp[0][1]=log(0.17)+aa[1][lea[0]];dp[0][2]=log(0.20)+aa[2][lea[0]];for(int i=1;i<n;i++)//第0天已经有了 for(int j=0;j<3;j++)    {double ma=-1e8; //是1非l int idx;for(int k=0;k<3;k++){if(dp[i-1][k]+aa[j][lea[i]]+bb[k][j]>ma){ma=dp[i-1][k]+aa[j][lea[i]]+bb[k][j];    idx=k;}}    pre[i][j]=idx;dp[i][j]=ma;    }     double ma=-1e8;int idx;     for(int j=0;j<3;j++)     {     if(dp[n-1][j]>ma)     {        ma=dp[n-1][j];     idx=j;     } } ans[n-1]=idx; for(int i=n-1;i>0;i--) { ans[i-1]=pre[i][idx];//前一天等于后一天的之前的最可能的天气,倒着递归。     idx=pre[i][idx]; //天气转为i-1天的天气,再往前推 } printf("Case #%d:\n",++ca); for(int i=0;i<n;++i){ if(ans[i]==0)puts("Sunny"); else if(ans[i]==1)puts("Cloudy"); else puts("Rainy"); }    }}return 0;}

0 0