1101上午考试T4
1101上午考试T4
题目大意:
有\(n\)轮比赛,最终成绩由这 n 轮比赛中赢的轮数决定。如果在第 i 轮比赛赛选择积极应战,并且前 i-1 轮比赛中取得了 j 胜的话,那么第 i 轮比赛的胜率概率为\(p[i][j]\),这里我们保证了对于同一个 i,\(p[i][j]\) 关于 j 的上升保持单调不上升(也就是说 \(p[i][j] >= p[i][j+1]\))。可以在某些轮比赛采取第二种策略,故意求败,也就是以 100% 的概率输掉该轮比赛,从而使之后的胜率可能更高, 现在已知看到了整个 p 数组,求一个最优的策略,使得期望赢的轮数最大。
期望概率DP.
期望DP不好搞,其实可以用概率DP来写.
最优情况下\(f[i][j]\)表示前\(i\)轮赢了\(j\)轮的概率是多少,转移方程就是:\(f[i][j] = f[i - 1][j - 1] * p[i][j - 1] + f[i - 1][j] * (1 - p[i][j])\).
然后统计答案就是:\(f[n][j] * j\).
至于为啥没有考虑第二种策略就是最优的....我也不知道
11.5更新:
好了现在我知道为啥没有第二种策略是最优的, 先设几个东西, \(p1\)表示p[1][0], \(p2\)表示p[2][0], \(p3\)表示p[2][1].
我们强制使用策略二, 可以获胜的轮数的期望是 : \(p2 * 1 = p2\);
我们不强制使用策略二, 可以获胜的轮数的期望是 : \(p1 * p3 * 2 + (1 - p1) * p2 * 1 + p1 * (1 - p3) * 1 = p1 * p3 + p1 + p2 - p1 * p2 = p1 * p3 + p2 + p1(1 - p2)\);
然后我们让两个式子都减去\(p2\), 那么一式变成了0, 二式变成了\(p1 * p3 + p1 * (1 - p2)\),显然二式大于零.
然后类比到多个应该也是一样的, 所以不使用策略二肯定更优.
这道题当然也可以用期望DP来写:
设\(f[i][j]\) 表示已经赢了\(j\)场, 从\(i + 1\)到\(n\) 的期望赢得场数, 可以得到DP转移方程:
\(f[i][j] = max(f[i + 1][j], (f[i + 1][j + 1] + 1) * p[i][j] + f[i + 1][j] * (1 - p[i][j])\);
前半部分表示使用策略二, 后半部分表示第\(i\)场赢 + 第\(i\)场输.
这个是概率DP的方程:
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int n;
double ans, p[N][N], f[N][N];
int main() {
cin >> n;
for(int i = 1;i <= n; i++)
for(int j = 0;j < i; j++) cin >> p[i][j];
f[0][0] = 1;
for(int i = 1;i <= n; i++) f[i][0] = f[i - 1][0] * (1 - p[i][0]);
for(int i = 1;i <= n; i++)
for(int j = 1;j <= n; j++)
f[i][j] = f[i - 1][j - 1] * p[i][j - 1] + f[i - 1][j] * (1 - p[i][j]);
for(int i = 1;i <= n; i++) ans += f[n][i] * i;
printf("%.2lf", ans);
return 0;
}
概率一般正着求, 期望一般倒着求.