第 45 届国际大学生程序设计竞赛(ICPC)亚洲网上区域赛模拟赛 D.Pokemon Ultra Sun(dp动态规划)

题目链接:https://ac.nowcoder.com/acm/contest/8688/D

题目描述
Two pokemons are in a battle.One is our and another is the opposite’s.

Our pokemon is in confusion and the opposite’s pokemon is frozen.

Once per turn , the opposite’s pokemon does nothing and our pokemon gives w damages to the opposite’s pokemon with a probability of P while gives w damages to itself with a probability of 1 − P.

Our pokemon has hp1 health points and the opposite’s pokemon has hp2 health points.

If one pokemon’s health points are zero or below zero, the game is over.

Your task is to calculate the expected number of turn.

输入描述:
The first line is an integer T(T ≤ 8) , the number of test cases.

For each test case, the first line contains three integers hp1, hp2, w(1 ≤ hp1, hp2, w ≤ 3000), representing our pokemon’s health points, the opposite’s health points and damage. The second line contains a real number P(0 < P < 1). which is described above.

输出描述:
For each test case, print the expected number of turn rounding to 6 digits after decimal in one line.

示例1

输入

1
1 1 1
0.5

输出

1.000000

题意

给出两个宝可梦,各有 hp1 hp2 的血量,第一个宝可梦的攻击力为 w ,每一回合有 p 的概率对对方造成 w 的伤害,1-p 的概率对自己造成 w 伤害,求能进行的回合的期望。

分析

我们设 dp[i][j] 表示两个宝可梦的血量分别为 i ,j 时的期望。
动态转移方程就是
dp[i][j] = (1 - p) * (dp[i - w][j] + 1) + p * (dp[i][j - w] + 1)(注意 i 或 j 小于 w 时的情况)
边界:dp[1][1] 的期望一定是 1 ;i 和 j 中有一个为 0 ,则期望一定为 0 。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int t;
int hp1,hp2,w;
double p;
double dp[3005][3005];
 
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset(dp, 0, sizeof(dp));
        scanf("%d%d%d%lf",&hp1,&hp2,&w,&p);
        dp[1][1] = 1;
        for(int i=1;i<=hp1;i++)
            for(int j=1;j<=hp2;j++)
            {
                double temp1,temp2;
                if(i - w < 0) temp1 = 0;
                else temp1 = dp[i - w][j];
                if(j - w < 0) temp2 = 0;
                else temp2 = dp[i][j - w];
                dp[i][j] = (1 - p) * (temp1 + 1.0) + p * (temp2 + 1.0);
            }
        printf("%.6lf\n",dp[hp1][hp2]);
    }
    return 0;  
}
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页