首页 > 代码库 > hdu 4865

hdu 4865

       当时比赛时没看这道题,后来看了下,感觉完全可以当做是条件概率之类的事情来做?其实这个是典型的隐马尔科夫模型的应用,这篇文章介绍的很不错http://blog.csdn.net/likelet/article/details/7056068

根本思想就是到第i天最优路径可以用第i-1天的最优路径推出来,也就是所谓的无后效性,其本质类似于递推,结合下概率方面的知识,递推一下就可以了

代码https://github.com/mlz000/hdu/blob/master/4865(Markov).cpp

#include<iostream>//Hidden Markov Model
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
double p1[3][3]={
    {0.5 ,0.375,0.125},
    {0.25,0.125,0.625},
    {0.25,0.375,0.375}
};
double p2[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 f[50][5];
int pre[50][5];
map<string,int>mp;
char ans[3][10]={"Sunny","Cloudy","Rainy"};
void print(int i,int j){
	if(i==0)	return;
	print(i-1,pre[i][j]);
	printf("%s\n",ans[j]);
}
int main(){
	mp["Dry"]=0,mp["Dryish"]=1,mp["Damp"]=2,mp["Soggy"]=3;
	int T,n;
	string s;
	cin>>T;
	for(int tt=1;tt<=T;++tt){
		f[1][0]=0.63,f[1][1]=0.17,f[1][2]=0.20;
		printf("Case #%d:\n",tt);
		cin>>n;
		for(int i=1;i<=n;++i){
			cin>>s;
			int k=mp[s];
			for(int j=0;j<3;++j){
				if(i==1)	f[i][j]=log(f[i][j])+log(p2[j][k]);
				else{
					f[i][j]=-1000000.0;
					for(int l=0;l<3;++l){
						if(f[i][j]<f[i-1][l]+log(p1[l][j])+log(p2[j][k])){
							f[i][j]=f[i-1][l]+log(p1[l][j])+log(p2[j][k]);
							pre[i][j]=l;
						}
					}
				}
			}
		}
		int last=0;
		if(f[n][1]>f[n][last])	last=1;
		if(f[n][2]>f[n][last])	last=2;
		print(n,last);
	}
	return 0;
}