Solution S o l u t i o n
E(x)=∑x∈AScore(x)×P(x)
E
(
x
)
=
∑
x
∈
A
S
c
o
r
e
(
x
)
×
P
(
x
)
只要考虑投了 m m 轮得到的概率和分数就好了。
概率可以这样DP。
ft,i,r,p,s f t , i , r , p , s 表示考虑前 t t 个骰子,没被丢出来,出了 (r,p,s) ( r , p , s ) 的概率。
时间复杂度 O(n5) O ( n 5 ) 。
#define show(x) cerr << #x << " = " << x << endl
using namespace std;
typedef long long ll;
typedef pair<int, int> Pairs;
const int N = 51;
inline char get(void) {
static char buf[100000], *S = buf, *T = buf;
if (S == T) {
T = (S = buf) + fread(buf, 1, 100000, stdin);
if (S == T) return EOF;
}
return *S++;
}
template<typename T>
inline void read(T &x) {
static char c; x = 0; int sgn = 0;
for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1;
for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';
if (sgn) x = -x;
}
int n;
int a[N], b[N], c[N];
double q[N][4];
double f[N][N][N][N];
double ans;
class RockPaperScissors {
public:
double bestScore(vector <int> Pr, vector <int> Pp, vector <int> Ps) {
n = Pr.size();
for (int i = 1; i <= n; i++) {
q[i][1] = (double)Pr[i - 1] / 300;
q[i][2] = (double)Pp[i - 1] / 300;
q[i][3] = (double)Ps[i - 1] / 300;
}
for (int i = 1; i <= n; i++) f[i][0][0][0] = 1;
for (int t = 1; t <= n; t++) {
for (int m = t; m >= 0; m--)
for (int r = 0; r <= m; r++)
for (int p = 0; p + r <= m; p++) {
int s = m - r - p;
double prob = (double)m / t;
for (int i = 1; i <= n; i++) {
f[i][r][p][s] *= (1 - prob);
if (i == t) continue;
if (r > 0) f[i][r][p][s] += f[i][r - 1][p][s] * prob * q[t][1];
if (p > 0) f[i][r][p][s] += f[i][r][p - 1][s] * prob * q[t][2];
if (s > 0) f[i][r][p][s] += f[i][r][p][s - 1] * prob * q[t][3];
}
}
}
for (int r = 0; r < n; r++)
for (int p = 0; p + r < n; p++)
for (int s = 0; s + p + r < n; s++) {
int m = r + p + s;
double pr = 0, pq = 0, ps = 0;
for (int i = 1; i <= n; i++) {
double cur = f[i][r][p][s];
pr += cur * q[i][1];
pq += cur * q[i][2];
ps += cur * q[i][3];
}
pr /= (n - m); pq /= (n - m); ps /= (n - m);
ans += max(max(pr + ps * 3, pq + pr * 3), ps + pq * 3);
}
return ans;
}
};