hdu4711Weather 概率dp

//第i个城市到第j个城市的概率ma[i][j]
//第i天的天气天气wet[i]
//第i个城市天气为j的概率wet_m[i][j]
//Hovey从0点開始,找出其概率最大的路线
//dp[i][j] 表示在第i天Hovey在第j个城市在全部路线的最大概率
//dp[i][j] = dp[i-1][k].p+ma[k][j]+wet_m[j][wet[i]]
//可是因为精度问题,须要取对数
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std ;
const int maxn = 1010 ;
const double inf = 1e50;
const double eps = 1e-14 ;
struct node
{
    int pre ;
    double p ;
}dp[maxn][maxn] ;
double ma[maxn][maxn] ;
double wet_m[maxn][maxn] ;
int wet[maxn] ;
int ans[maxn] ;
int main()
{
    //freopen("in.txt" ,"r" ,stdin) ;
    int T ;
    scanf("%d" ,&T) ;
    int n , m , w ;
    while(T--)
    {
        scanf("%d%d%d", &n , &m , &w) ;
        for(int i = 1;i <= n;i++)
        scanf("%d" , &wet[i]) ;
        for(int i = 0;i < m;i++)
        for(int j = 0 ;j < m;j++)
        {
            scanf("%lf" , &ma[i][j]) ;
            if(ma[i][j]<=0)ma[i][j] = -inf ;
            else
            ma[i][j] = log(ma[i][j]) ;
        }
        for(int i = 0;i < m;i++)
        for(int j = 0;j < w;j++)
        {
            scanf("%lf" , &wet_m[i][j]) ;
            if(wet_m[i][j] <= 0)wet_m[i][j] = -inf ;
            else
            wet_m[i][j] = log(wet_m[i][j]);
        }
        //memset(dp , 0 , sizeof(dp)) ;
        for(int i = 0;i <= n;i++)
        for(int j = 0;j <= m;j++)
        dp[i][j].p = -inf ;
        dp[0][0].p = 0 ;
        for(int i = 1;i <= n;i++)
          for(int j = 0 ;j < m;j++)
           for(int k = 0;k < m ;k++)
           {
               double temp = dp[i-1][k].p+ma[k][j]+wet_m[j][wet[i]] ;
               if(temp > dp[i][j].p)
               {
                   dp[i][j].p = temp;
                   dp[i][j].pre = k ;
               }
           }
        double Max = -inf ;
        int pos = 0;
        for(int j = 0;j < m;j++)
        if(dp[n][j].p > Max+eps)
        {
            pos = j ;
            Max = dp[n][j].p ;
        }
        int  pr = pos ;
        for(int i = n ;i > 0 ;i--)
        {
            ans[i] = pr;
            pr = dp[i][pr].pre ;
        }
        for(int i = 1;i <= n;i++)
        printf("%d%c" , ans[i] , i == n ?' ':' ') ;
    }


}













































原文地址:https://www.cnblogs.com/jhcelue/p/6780006.html