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

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.

The ﬁrst line is an integer T(T ≤ 8) , the number of test cases.

For each test case, the ﬁrst 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
0.5


1.000000


#### 分析

dp[i][j] = (1 - p) * (dp[i - w][j] + 1) + p * (dp[i][j - w] + 1)（注意 i 或 j 小于 w 时的情况）

#### 代码

#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;
}


04-20 1438
12-20 1172
10-31 4109