题意:有n张+1和m张-1的牌,可以中途停止摸牌,问按最优策略摸牌,最后期望得分。
由于有决策存在,那么就要满足有最优子结构,而我们可以通过计算期望来得知该状态的好坏,也就是知道在该状态下我们期望得更多分还是失去更多的分。那么有一个很显然的结论是,如果继续拿牌你期望得分是小于0的,那么你不如终止摸牌。
既然满足最优子结构了,那么我们就考虑dp。这个dp的状态是,我们设dp[i][j]为还剩i张+1,j张-1的期望得分,那么我们的转移方程是
d
p
[
i
]
[
j
]
=
m
a
x
(
0
,
(
d
p
[
i
−
1
]
[
j
]
+
1
)
∗
i
i
+
j
+
(
d
p
[
i
]
[
j
−
1
]
−
1
)
∗
j
i
+
1
)
dp[i][j]=max(0,(dp[i-1][j]+1)*\frac{i}{i+j}+(dp[i][j-1]-1)*\frac{j}{i+1})
dp[i][j]=max(0,(dp[i−1][j]+1)∗i+ji+(dp[i][j−1]−1)∗i+1j)初始状态为
d
p
[
0
]
[
j
]
=
0
dp[0][j]=0
dp[0][j]=0,
d
p
[
i
]
[
0
]
=
i
dp[i][0]=i
dp[i][0]=i。
代码:
#include <bits/stdc++.h>
using namespace std;
int r,b;
double dp[5002][5002];
int main()
{
scanf("%d%d",&r,&b);
for(int i=1;i<=r;++i)
dp[i][0]=i;
for(int i=1;i<=b;++i)
dp[0][i]=0;
for(int i=1;i<=r;++i)
{
for(int j=1;j<=b;++j)
{
dp[i][j]=max(0.0,(dp[i-1][j]+1)*((double)i/(i+j))+(dp[i][j-1]-1)*((double)j/(i+j)));
}
}
double ji=dp[r][b]*1e7;
long long gg=ji;
if(gg%1000000>=5)
dp[r][b]-=5*1e-7;
printf("%.6lf\n",dp[r][b]);
return 0;
}