UVAlive6620 Josephina and RPG

来源:互联网 发布:什么是中文域名 编辑:程序博客网 时间:2024/05/22 03:43

这是一道容易的概率DP题link
这道题的题意是:给出一个队伍的组合和对另一种组合获胜的概率,之后求出战胜给出敌人的概率。我们首先想到的是对于一个组合,我们要不要选他,那么这样状态就很容易想出来了:用dp[i][j] 表示对第前i个敌人,当前采用第j个队伍组合,在已知各个队伍组合之间的胜率之后,我们的决策就变成了dp[i][j] = p[j][k]*max(dp[i-1][j],dp[i-1][k]) ,之后所有的组合保存在dp数组的最后行,我们找到其中最大的就可以了:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <vector>#include <ctime>#include <cstdlib>#define ll long longusing namespace std;double dp[10010][150];double p[150][150];int a[15000];int main(){    int M;    while(scanf("%d",&M)!= EOF)    {        memset(dp,0,sizeof(dp));        memset(p,0,sizeof(p));        memset(a,0,sizeof(a));        int n = (M-1)*M*(M-2)/6;        for(int i = 0;i<n;i++)        {            for(int j = 0;j<n;j++)            {                scanf("%lf",&p[i][j]);            }        }        int m;        scanf("%d",&m);        for(int i =1;i<=m;i++)        {            scanf("%d",&a[i]);        }        for(int i = 0;i<=n;i++)        {            dp[0][i] = 1;        }        for(int i = 1;i<=m;i++)        {            for(int j = 0;j<n;j++)            {                dp[i][j] = max(dp[i-1][j] * p[j][a[i]],dp[i][j]);                dp[i][a[i]] = max(dp[i-1][j] * p[j][a[i]],dp[i][a[i]]);            }        }        double ans = 0;        for(int i = 0;i<n;i++)        {            ans = max(ans,dp[m][i]);        }        printf("%.6lf\n",ans);    }    return 0;}