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\)很大的时候实现这个递推的过程。

posted @ 2022-09-06 10:56  浅渊  阅读(67)  评论(0)    收藏  举报