hdu 4865 Peter's Hobby(2014 多校聯合第一場 E)

Peter's Hobby

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 545    Accepted Submission(s): 237


Problem Description
Recently, Peter likes to measure the humidity of leaves. He recorded a leaf humidity every day. There are four types of leaves wetness: Dry , Dryish , Damp and Soggy. As we know, the humidity of leaves is affected by the weather. And there are only three kinds of weather: Sunny, Cloudy and Rainy.For example, under Sunny conditions, the possibility of leaves are dry is 0.6.
Give you the possibility list of weather to the humidity of leaves.


The weather today is affected by the weather yesterday. For example, if yesterday is Sunny, the possibility of today cloudy is 0.375.
The relationship between weather today and weather yesterday is following by table:


Now,Peter has some recodes of the humidity of leaves in N days.And we know the weather conditons on the first day : the probability of sunny is 0.63,the probability of cloudy is 0.17,the probability of rainny is 0.2.Could you know the weathers of these days most probably like in order?

題目大意:有三種天氣和四種溼度,給出在每種天氣下四種溼度的概率,和天氣之間的轉移概率,現在給出一個n天的溼度序列,要求給出一個概率最大的天氣序列。

思路:很簡單的概率DP,轉移概率和狀態概率都給好了,設dp[i][j]表示第i天是第j種天氣的最大概率,然後pre[i][j]來記錄序列順序。

假設第i-1天是第j1種天氣,第i天是j2種天氣,天氣轉移概率爲p1[j1][j2],第i天的溼度爲x,在第j2種天氣下x溼度的概率爲p2[j2][x],則有:

dp[i][j2]=max(dp[i-1][j1]*p1[j1][j2]*p2[j2][x]),記錄最大值是由哪一個j1轉移過來的,用pre[i][j2]記錄。最後求得最大的dp[n][j],根據pre數組輸出路徑即可。

注:題目中說由於dp[n][j]可能很小,用double乘可能會掉精度,所以要用log,但是我直接乘也過了,可能是運氣比較好吧,以後這種問題還是要多注意。

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string>
#include <map>
#include <vector>
#define maxn 55
using namespace std;
double dp[55][3];
int pre[55][3];
map<string,int> mp;
string str;
double p1[3][4]={0.6,0.2,0.15,0.05,0.25,0.3,0.2,0.25,0.05,0.1,0.35,0.5};
double p2[3][3]={0.5,0.375,0.125,0.25,0.125,0.625,0.25,0.375,0.375};
void init()
{
    mp.insert(make_pair("Dry",0));
    mp.insert(make_pair("Dryish",1));
    mp.insert(make_pair("Damp",2));
    mp.insert(make_pair("Soggy",3));
}
int main()
{
    int ncase,T=0;
    scanf("%d",&ncase);
    init();
    while(ncase--)
    {
        printf("Case #%d:\n",++T);
        int n;
        scanf("%d",&n);
        cin>>str;
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<3;j++)
            dp[i][j]=0;
        }
        int lab=mp[str];
        memset(pre,0,sizeof(pre));
        dp[1][0]=0.63*p1[0][lab];
        dp[1][1]=0.17*p1[1][lab];
        dp[1][2]=0.2*p1[2][lab];
        for(int i=2;i<=n;i++)
        {
            cin>>str;
            int lab=mp[str];
            for(int j=0;j<3;j++)
            {
                for(int k=0;k<3;k++)
                {
                    double pp=dp[i-1][k]*p2[k][j]*p1[j][lab];
                    if(pp>dp[i][j])
                    {
                        dp[i][j]=pp;
                        pre[i][j]=k;
                    }
                }
            }
        }
        vector<int> ans;
        double mi=0;
        int po;
        for(int i=0;i<3;i++)
        {
            if(dp[n][i]>mi)
            {
                mi=dp[n][i];
                po=i;
            }
        }
        ans.push_back(po);
        int now=n;
        while(now!=1)
        {
            po=pre[now][po];
            ans.push_back(po);
            now--;
        }
        for(int i=n-1;i>=0;i--)
        {
            if(ans[i]==0)
            printf("Sunny\n");
            else if(ans[i]==1)
            printf("Cloudy\n");
            else
            printf("Rainy\n");
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章