首页 > 代码库 > HDU 4865 Peter's Hobby --概率DP
HDU 4865 Peter's Hobby --概率DP
题意:第i天的天气会一定概率地影响第i+1天的天气,也会一定概率地影响这一天的湿度.概率在表中给出。给出n天的湿度,推测概率最大的这n天的天气。
分析:这是引自机器学习中隐马尔科夫模型的入门模型,其实在这里直接DP就可以了
定义:dp[i][j]为第i天天气为j(0,1,2分别表示三个天气)的概率,path[i][j]记录路径,path[i][j] = k 意思是前一天天气为k时,这一天有最大的概率是天气j。
做一个三重循环,对于每天,枚举今天的天气,再在里面枚举昨天的天气,则有:
dp[i][j] = max(dp[i-1][k]*yto[k][j]*wtoh[j][humi[i]])
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <string>#define eps 1e-4using namespace std;string weather[4] = {"Sunny","Cloudy","Rainy"};double yto[3][3]={{0.5,0.375,0.125},{0.25,0.125,0.625},{0.25,0.375,0.375}};double wtoh[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}};int humi[55],path[55][3],ans[55];double dp[55][4];int gethum(string ss){ if(ss == "Dry") return 0; else if(ss == "Dryish") return 1; else if(ss == "Damp") return 2; else return 3;}int main(){ int t,cs = 1,i,j,n,k; string ss; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) { cin>>ss; int hum = gethum(ss); humi[i] = hum; } for(i=0;i<=n;i++) for(j=0;j<3;j++) dp[i][j] = 0.0; memset(path,0,sizeof(path)); dp[0][0] = 0.63*wtoh[0][humi[0]]; dp[0][1] = 0.17*wtoh[1][humi[0]]; dp[0][2] = 0.20*wtoh[2][humi[0]]; for(i=1;i<n;i++) { for(j=0;j<3;j++) //today‘s weather { for(k=0;k<3;k++) //yesterday‘s weather { double P = dp[i-1][k]*yto[k][j]*wtoh[j][humi[i]]; if(P > dp[i][j]) { dp[i][j] = P; path[i][j] = k; } } } } int now = 0; for(i=0;i<3;i++) { if(dp[n-1][i] > dp[n-1][now]) now = i; } ans[n-1] = now; for(i=n-2;i>=0;i--) { now = path[i+1][now]; ans[i] = now; } printf("Case #%d:\n",cs++); for(i=0;i<n;i++) cout<<weather[ans[i]]<<endl; } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。