HDU 4865 Peter's Hobby

$dp$。

这题的本质和求一个有向无环图的最长路径长度的路径是一样的。

$dp[i][j]$表示到第$i$天,湿度为$a[i]$,是第$j$种天气的最大概率。记录一下最大概率是$i-1$天哪一种天气推过来的,然后就可以得到路径了。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0);
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar();
    x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c))
    {
        x = x * 10 + c - '0';
        c = getchar();
    }
}

double ts[5][5]={
    { 0,0,0,0,0},
    { 0, 0.6, 0.2, 0.15, 0.05},
    { 0, 0.25, 0.3, 0.2, 0.25},
    { 0, 0.05, 0.1, 0.35, 0.5},
};
double tt[5][5]={
    { 0 , 0 , 0},
    { 0 , 0.5, 0.375, 0.125 },
    { 0 , 0.25, 0.125, 0.625 },
    { 0 , 0.25, 0.375, 0.375 },
};
double dp[60][5];
int T,n,p[60][5],a[60],cas=1;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            char s[10]; scanf("%s",s);
            if(strcmp(s,"Dry")==0) a[i]=1;
            else if(strcmp(s,"Dryish")==0) a[i]=2;
            else if(strcmp(s,"Damp")==0) a[i]=3;
            else a[i]=4;
        }

        memset(p,-1,sizeof p);
        memset(dp,0,sizeof dp);

        dp[1][1]=ts[1][a[1]]*0.63;
        dp[1][2]=ts[2][a[1]]*0.17;
        dp[1][3]=ts[3][a[1]]*0.2;

        for(int i=2;i<=n;i++)
        {
            for(int j=1;j<=3;j++)
            {
                for(int k=1;k<=3;k++)
                {
                    if(dp[i-1][k]*tt[k][j]*ts[j][a[i]]>dp[i][j])
                    {
                        dp[i][j]=dp[i-1][k]*tt[k][j]*ts[j][a[i]];
                        p[i][j]=k;
                    }
                }
            }
        }

        stack<int>S;

        double mx=0; int idx=0;
        for(int j=1;j<=3;j++) if(dp[n][j]>mx) mx=dp[n][j],idx=j;

        int now=idx, r=n;
        while(1)
        {
            S.push(now);
            now=p[r][now];
            r--;
            if(now==-1) break;
        }

        printf("Case #%d:\n",cas++);
        while(!S.empty())
        {
            int x=S.top(); S.pop();
            if(x==1) printf("Sunny\n");
            else if(x==2) printf("Cloudy\n");
            else printf("Rainy\n");
        }

    }
    return 0;
}

 

posted @ 2017-02-22 09:56  Fighting_Heart  阅读(150)  评论(0编辑  收藏  举报