ACM 2013 长沙区域赛 Josephina and RPG (概率dp)

ZOJ - 3735   

题目大意:

       游戏共有m个角色,3个角色组成一个战队,有C_{m}^{3}个战队,i战队打败j战队的概率为p[i][j].游戏有n轮,每轮对方都会有一个战队与你对战,游戏开始时你可以选择任意一个战队进行游戏,每轮结束后如果你胜出,可以进行下一轮,并且可以把自己使用的战队更换为刚打败的战队,求通关的最大胜率。

题解:

dp[i][j]代表是对战前i个队伍后且当前的队伍是j的最大胜率。

不换的情况

          dp[i][j]=dp[i-1][j]*a[j][enemy]      dp[i][j]可以由dp[i-1][j]转移过来

换的情况

        dp[i][enemy]=dp[i-1][j]*a[j][enemy]  第i-1轮用j队和enemy对打

        这里的乘以概率只是为了得到获胜的概率,因为只有获胜才能往下继续,至于获胜之后的两种选择换和不换才产生了循环里的两个语句,一个换,一个不换。

        有人可能会觉得,为什么不乘以50%呢,就是换是50%,不换是50%

        注意这里是可能换可能不换,至于到底换不换我们是看怎样做最后结果最大,而不是每次一定是50%的几率换,50%的几率不换,所以不能乘以50%,这就相当于是dfs中选还是不选,两种情况。

 

      最后diss一下题意,本场比赛真是读题到自闭,好久才搞明白,体验很不爽

#include<bits/stdc++.h>
#include<cstring>
using namespace std;
#define ll long long
double a[150][150];
double dp[10010][150];
int main()
{
    //freopen("input.txt","r",stdin);
    int m;
    while(cin>>m)
    {

        int len=m*(m-1)*(m-2)/6;
        for(int i=1; i<=len; ++i)
            for(int j=1; j<=len; ++j)
                cin>>a[i][j];
        //dp[i][j]代表是对战前i个队伍后且当前的队伍是j的最大胜率。。
        int n;
        cin>>n;
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=len; ++i)
            dp[0][i]=1;
        int enemy;
        for(int i=1; i<=n; ++i)
        {
            cin>>enemy;
            ++enemy;
            for(int j=1; j<=len; ++j)
            {
                dp[i][j]=max(dp[i][j],dp[i-1][j]*a[j][enemy]);//不换
                dp[i][enemy]=max(dp[i][enemy],dp[i-1][j]*a[j][enemy]);//换
            }
        }
        double ans=0;
        for(int i=1; i<=len; ++i)
            ans=max(ans,dp[n][i]);
        cout<<fixed<<setprecision(8)<<ans<<endl;
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值