hdu 4800 Josephina and RPG【dp】

Josephina and RPG

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1487    Accepted Submission(s): 455
Special Judge

Problem Description

A role-playing game (RPG and sometimes roleplaying game) is a game in which players assume the roles of characters in a fictional setting. Players take responsibility for acting out these roles within a narrative, either through literal acting or through a process of structured decision-making or character development.
Recently, Josephina is busy playing a RPG named TX3. In this game, M characters are available to by selected by players. In the whole game, Josephina is most interested in the "Challenge Game" part.
The Challenge Game is a team play game. A challenger team is made up of three players, and the three characters used by players in the team are required to be different. At the beginning of the Challenge Game, the players can choose any characters combination as the start team. Then, they will fight with N AI teams one after another. There is a special rule in the Challenge Game: once the challenger team beat an AI team, they have a chance to change the current characters combination with the AI team. Anyway, the challenger team can insist on using the current team and ignore the exchange opportunity. Note that the players can only change the characters combination to the latest defeated AI team. The challenger team gets victory only if they beat all the AI teams.
Josephina is good at statistics, and she writes a table to record the winning rate between all different character combinations. She wants to know the maximum winning probability if she always chooses best strategy in the game. Can you help her?

Input

There are multiple test cases. The first line of each test case is an integer M (3 ≤ M ≤ 10), which indicates the number of characters. The following is a matrix T whose size is R × R. R equals to C(M, 3). T(i, j) indicates the winning rate of team i when it is faced with team j. We guarantee that T(i, j) + T(j, i) = 1.0. All winning rates will retain two decimal places. An integer N (1 ≤ N ≤ 10000) is given next, which indicates the number of AI teams. The following line contains N integers which are the IDs (0-based) of the AI teams. The IDs can be duplicated.

Output

For each test case, please output the maximum winning probability if Josephina uses the best strategy in the game. For each answer, an absolute error not more than 1e-6 is acceptable.

Sample Input

4

0.50 0.50 0.20 0.30

0.50 0.50 0.90 0.40

0.80 0.10 0.50 0.60

0.70 0.60 0.40 0.50

3

0 1 2

Sample Output

0.378000

Source

2013 Asia Changsha Regional Contest


题目大意:

一共有M个人物,其中游戏开始的时候,需要从中选择3个人物组成一队,那么一共能够组出来C(m,3)个队伍,对应给你一个C(m,3)*C(m,3)的一个图表 ,表示第i个队伍打败第J个队伍的胜率。这个游戏需要你打败N个队伍,按照输入顺序来打败,每一次打败一个队伍之后,可以有一个机会和这个被你打败的队伍进行交换,就是将角色从第i个队伍,变成第j个队伍,当然也考虑不交换,但是交换队伍只能和刚刚打败的那个队伍交换,不能和之前打败的队伍进行交换,那么问将这N个队伍全部打败的最高胜率是多少。

分析样例;

一开始选择3号队伍,用其击败0、1号队伍之后,和队伍1交换,然后用队伍1来打败队伍2,得到最高胜率:0.7*0.6*0.9;


思路:


1、显然这个题贪心是行不通的,那么考虑dp:设定数组dp【i】【j】表示用第j个队伍来打败第i个需要打败的队伍的最高胜率。


2、那么其状态转移方程并不难想到:

①dp【i】【j】=max(dp【i】【j】,dp【i-1】【k】*a【j】【b【i】】)【j==k,b【i】表示第i个需要打败的队伍】,其表示如果不换队伍,用j号队伍打完了第i-1个队伍之后,继续用j号队伍又打败了第i个队伍的胜率,如果其大于了dp【i】【j】,那么更新dp【i】【j】为这个值。

②dp【i】【j】=max(dp【i】【j】,dp【i-1】【k】*a【j】【b【i】】)【j!=k&&j==b【i-1】】,其表示如果交换队伍,用k号队伍打完了第i-1个队伍之后,用b【i-1】号队伍来打败第i个队伍的胜率,如果其大于了dp【i】【j】,那么更新dp【i】【j】这个值。


3、那么dp【n-1】【i】(0<=i<=n-1)中的最大值,就是答案。


4、注意初始化数组即可。


Ac代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
double a[125][125];
int b[10100];
double dp[10100][125];
int cal(int m,int tt)
{
    int tmp=1;
    for(int i=m;i>=m-2;i--)
    {
        tmp*=i;
    }
    for(int i=1;i<=3;i++)
    {
        tmp/=i;
    }
    return tmp;
}
int main()
{
    int m;
    while(~scanf("%d",&m))
    {
        int r=cal(m,3);
        for(int i=0;i<r;i++)
        {
            for(int j=0;j<r;j++)
            {
                scanf("%lf",&a[i][j]);
            }
        }
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&b[i]);
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<r;j++)
            {
                dp[i][j]=0;
            }
        }
        for(int i=0;i<r;i++)
        {
            dp[0][i]=a[i][b[0]];
        }
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<r;j++)
            {
                for(int k=0;k<r;k++)
                {
                    if(j==k)
                    {
                        dp[i][j]=max(dp[i][j],dp[i-1][j]*a[j][b[i]]);
                    }
                    else if(j==b[i-1])
                    {
                        dp[i][j]=max(dp[i][j],dp[i-1][k]*a[j][b[i]]);
                    }
                }
            }
        }
        double ans=0;
        for(int i=0;i<r;i++)
        {
            ans=max(ans,dp[n-1][i]);
        }
        printf("%lf\n",ans);
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值