题目大意
太长不想写qwq
题解
首先会发现,如果我们按照每一轮往后dp是行不通的,因为这样需要表示当前所有牌的选择状态。
于是我们令
表示前
张牌中,
张牌被选了的期望伤害是多少。然后我yy了一个递推式,调了一会儿发现这样行不通……因为第
张牌的选择状态依赖于前面某些牌的选择状态。
既然后面依赖前面,那我们就反过来dp呗……
表示
到
中,有
轮被占用的期望伤害是多少。注意这里
不是多少牌被选择,因为可能有一轮什么牌都不选。
于是递推式就比较好办了,我们枚举当前的牌选或不选,如果选,在第几个被选。由于
并不会影响
之前的牌的选择,我们就可以大胆dp了。
于是直接
dp就没了。目前跑得飞快
#include <bits/stdc++.h>
using namespace std;
int T, n, r, d[225];
double f[225][135], p[225];
int main() {
for (scanf("%d", &T); T--;) {
scanf("%d%d", &n, &r);
for (int i = 1; i <= n; i++)
scanf("%lf%d", p + i, d + i);
for (int i = 0; i <= r; i++) f[n + 1][i] = 0;
for (int i = n; i > 0; i--) {
double mul = 1, pp = 1 - p[i];
for (int j = 1; j <= r; j++) {
mul *= pp;
f[i][j] = (1 - mul) * (f[i + 1][j - 1] + d[i]) + mul * f[i + 1][j];
}
}
printf("%.10lf\n", f[1][r]);
}
return 0;
}