意: 真难解释清楚,给你一个海藻的状态序列,让你找出一个最有可能的天气序列,前一天的天气能影响今天的天气,海藻的状态受天气的影响。
(从题目中应该是读不出他是怎样影响的,具体看下面的推荐的链接)
思路: 这其实是隐马尔可夫模型(HMM)的一个应用,根据可观察状态的序列找到一个最可能的隐藏状态序列,
隐马尔可夫模型介绍见这里:点击打开链接 dp[i][j]表示第i天天气为j的概率,
dp[i][j]=dp[i-1][k]*wea[k][j]*lea[j][num[i]],记录路径,最后输出最有可能的路径,
根据最后一天的概率来看。
(从题目中应该是读不出他是怎样影响的,具体看下面的推荐的链接)
思路: 这其实是隐马尔可夫模型(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;
}