HDU4865

意: 真难解释清楚,给你一个海藻的状态序列,让你找出一个最有可能的天气序列,前一天的天气能影响今天的天气,海藻的状态受天气的影响。
(从题目中应该是读不出他是怎样影响的,具体看下面的推荐的链接) 
思路: 这其实是隐马尔可夫模型(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值