hdu4865(概率DP)

题意:已知前一天和今天的天气概率,某天的天气概率和叶子的潮湿程度的概率,n天叶子的湿度,求n天最有可能的天气情况。

思路:概率DP,dp[i][j]表示第i天天气为j的概率,状态转移如下:dp[i][j] = max(dp[i][j, dp[i-1][k]*table2[k][j]*table1[j][col] ) 

代码如下:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
#include <string>
#include <stack>
#include <iostream>
#define N 55
using namespace std;
double dp[N][5];
char s[10];
int pre[N][5];
double table1[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 table2[3][3] = { {0.5,0.375,0.125}, {0.25,0.125,0.625}, {0.25,0.375,0.375} };
int get_col(char *s)
{
    if(strcmp(s,"Dry") == 0)    return 0;
    if(strcmp(s,"Dryish") == 0)  return 1;
    if(strcmp(s,"Damp") == 0)   return 2;
    return 3;
}
map<int,string> mp;
int main()
{
    mp[0] = "Sunny";
    mp[1] = "Cloudy";
    mp[2] = "Rainy";

    int t,cas = 1;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        memset(dp,0,sizeof(dp));
        int i,j,k;
        scanf("%s",s);
        int col = get_col(s);
        dp[1][0] = 0.63*table1[0][col];
        dp[1][1] = 0.17*table1[1][col];
        dp[1][2] = 0.20*table1[2][col];
        for(i = 2; i <= n; i++)
        {
            scanf("%s",s);
            col = get_col(s);
            for(j = 0; j < 3; j++)
                for(k = 0; k < 3; k++)
                {
                    double temp = dp[i-1][k]*table2[k][j]*table1[j][col];
                    if(dp[i][j] < temp){
                        dp[i][j] = temp;
                        pre[i][j] = k;
                    }
                }
        }
        double temp = 0;
        for(i = 0; i < 3; i++)
            if(dp[n][i] > temp)
            {
                k = i;
                temp = dp[n][i];
            }
       // cout<<k<<endl;
        //cout<<temp<<endl;
        //for(i = 1; i <= n; i++){
           // for(j = 0; j < 3; j++)
         //       cout<<dp[i][j]<<" ";
       //     cout<<endl;}

     //   for(i = 1; i <= n; i++){
   //         for(j = 0; j < 3; j++)
 //               cout<<pre[i][j]<<" ";
//           / cout<<endl;}
        printf("Case #%d:\n",cas++);
        stack<string> q;
        while(n)
        {
    //        printf("%s\n",mp[k]);
          //  cout<<mp[k]<<endl;
            q.push(mp[k]);
            k = pre[n][k];
  //          cout<<k<<endl;
            n--;
        }
        while(!q.empty())   {cout<<q.top()<<endl;q.pop();}


    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值