首页 > 代码库 > 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;}
View Code