ABC266 E(概率dp)
题目链接
题目大意:投骰子每次会得到一个点数,可以选择是否继续,如果继续的将会得到一个新的点数,如果结束那么当前的点数将是最后的所得到的点数。求所能得到的最大期望值是多少。
思路:
算是一个比较典型的概率\(dp\),考虑是否继续投下去,如果下一次投的点数小于当前的点数,那肯定不会投下去而是选择结束,否则继续投下去。这样我们就得到了\(dp\)的转移方程\(dp[i] = \begin{cases} dp[i - 1] + dp[i]&j < dp[i - 1]\\dp[i] + j&j \geqslant dp[i - 1]\end{cases}\), \(dp[i] = dp[i] / 6\)
int n;
std::cin >> n;
std::vector<double> dp(n + 1);
dp[1] = 3.5;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= 6; j++) {
if (j >= dp[i - 1]) dp[i] += 1.0 * j;
else dp[i] += dp[i - 1];
}
dp[i] /= 6;
}
std::cout << std::fixed << std::setprecision(10) << dp[n] << "\n";
拓展: 此题的数据范围只有\(n\leq 100\)所以这么写是肯定可以的,但是如果\(n \leq 10 ^ 9\)那就需要去找一些性质了,比如我们知道当\(n = 10\)的时候期望就已经达到了\(5.65\),那么我们可以发现此时的状态转移已经确定了,只有当点数是\(6\)的时候才会继续下去,所以\(dp[i] = dp[i] + (j \leq 5 ? dp[i - 1] : 6)\).那么我们就可以考虑用一个矩阵加速这个递推,这样我们就可以在\(n\)很大的时候实现这个递推的过程。

浙公网安备 33010602011771号