每一轮,你都随机选一个数字
x
x
x,然后把它放在自己的集合
S
S
S 中 若
x
=
max
{
S
}
x=\max\{S\}
x=max{S},则你可以继续选数字 否则,你获得分数
∣
S
∣
2
|S|^2
∣S∣2
问你获得分数的期望
1
≤
n
≤
100
1\le n\le 100
1≤n≤100
思路
期望倒着推,别想着正着推拉! 期望的设法一般都很单纯(我遇到的题目中) 设
d
p
[
i
]
dp[i]
dp[i] 表示开始选到数字
i
i
i,最后的分数?
N
o
!
\color{red}{No!}
No!
注意,这里的分数为
∣
S
∣
2
|S|^2
∣S∣2 我们有
e
(
x
2
)
≠
e
2
(
x
)
e(x^2)\ne e^2(x)
e(x2)=e2(x),所以我们的设法不能直接这么设!(这个也是很套路的)
设
d
p
[
i
]
dp[i]
dp[i] 表示目前选到数字
i
i
i,最后的集合大小 设
d
p
2
[
i
]
dp2[i]
dp2[i] 表示目前选到数字
i
i
i,最后的集合大小的平方,也就是分数 开始转移! 注意转移也是很套路的。等号后面跟着的就是概率 * (下一个状态 + 贡献)
d
p
[
i
]
=
∑
j
=
i
n
p
j
×
(
d
p
[
j
]
+
1
)
+
∑
j
=
1
i
−
1
p
j
×
1
d
p
2
[
i
]
=
∑
j
=
i
n
p
j
×
(
d
p
2
[
j
]
+
2
d
p
[
j
]
+
1
)
+
∑
j
=
1
i
−
1
p
j
×
1
2
dp[i]=\sum_{j=i}^n p_j\times (dp[j]+1)+\sum_{j=1}^{i-1}p_j\times 1\\ dp2[i]=\sum_{j=i}^n p_j\times (dp2[j]+2dp[j]+1)+\sum_{j=1}^{i-1}p_j\times 1^2
dp[i]=j=i∑npj×(dp[j]+1)+j=1∑i−1pj×1dp2[i]=j=i∑npj×(dp2[j]+2dp[j]+1)+j=1∑i−1pj×12 这里又有很多个问题了:
对于
d
p
[
i
]
dp[i]
dp[i] 的转移: (1)下一步有哪些?下一步选的数字为
j
j
j,要么是还能继续选 (
j
≥
i
j\ge i
j≥i) ,那么期望就是
p
j
(
d
p
[
j
]
+
1
)
p_j(dp[j]+1)
pj(dp[j]+1),这里
+
1
+1
+1 是因为你多选了一个数字,集合大小就
+
1
+1
+1了; 要么是不能选了 (
j
<
i
j < i
j<i ),期望就是
p
j
×
1
p_j\times1
pj×1 (2)等式两边自己包含自己?把右边关于
d
p
[
i
]
dp[i]
dp[i] 的系数移到等式左边,然后就能变成
d
p
[
i
]
=
S
o
m
e
t
h
i
n
g
1
−
p
i
dp[i]=\frac{Something}{1-p_i}
dp[i]=1−piSomething
对于
d
p
2
[
i
]
dp2[i]
dp2[i] 的转移: (1)下一步的贡献怎么算?容易得到
e
(
(
x
+
1
)
2
)
=
e
(
x
2
)
+
e
(
2
x
)
+
e
(
1
)
=
e
(
x
2
)
+
2
e
(
x
)
+
1
e((x+1)^2)=e(x^2)+e(2x)+e(1)=e(x^2)+2e(x)+1
e((x+1)2)=e(x2)+e(2x)+e(1)=e(x2)+2e(x)+1 所以中间展开就是这样了,因为我们根据定义,是从
e
(
x
2
)
推
到
e
(
(
x
+
1
)
2
)
e(x^2) 推到 e((x+1)^2)
e(x2)推到e((x+1)2)
e
(
x
2
)
≠
e
2
(
x
)
e(x^2)\ne e^2(x)
e(x2)=e2(x)
e
(
x
2
)
≠
e
2
(
x
)
e(x^2)\ne e^2(x)
e(x2)=e2(x)
e
(
x
2
)
≠
e
2
(
x
)
e(x^2)\ne e^2(x)
e(x2)=e2(x) 嗯,好多了… (2)最后面的是
p
j
×
1
2
p_j\times 1^2
pj×12,我觉得是这样的,因为下一步无法操作了,贡献就是
1
2
1^2
12 呀 (3)我们发现
我
们
算
出
来
的
根
本
就
不
是
集
合
大
小
,
而
是
操
作
次
数
呀
!
\color{red}{我们算出来的根本就不是集合大小,而是操作次数呀!}
我们算出来的根本就不是集合大小,而是操作次数呀! 最后让你算
e
(
i
2
)
e(i^2)
e(i2),但是相当于我们算的是
e
(
(
i
−
1
)
2
)
e((i-1)^2)
e((i−1)2) 嗯?你不会写成 答案 =
d
p
2
[
i
]
+
1
dp2[i]+1
dp2[i]+1 吧 (…) 答案是
d
p
2
[
i
]
+
2
d
p
[
i
]
+
1
\color{red}{dp2[i]+2dp[i]+1}
dp2[i]+2dp[i]+1
代码
时间复杂度:
O
(
n
2
log
n
)
O(n^2\log n)
O(n2logn),其实可以优化成
O
(
n
)
O(n)
O(n),无所谓!
#include<bits/stdc++.h>#defineIOSios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;typedeflonglong ll;voidshow(){std::cerr << endl;}template<typename T,typename... Args>voidshow(T x,Args... args){std::cerr <<"[ "<< x <<" ] , ";show(args...);}constint MAX =150;constint MOD =998244353;constint INF =0x3f3f3f3f;const ll LINF =0x3f3f3f3f3f3f3f3f;constdouble EPS =1e-5;
ll qpow(ll a,ll n){/* */ll res =1LL;while(n){if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){a%=p;ll res =1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){/* */ll res =1LL;while(n){if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return0;}return res;}
ll inv(ll a){/* */returnqpow(a,MOD-2);}
ll inv(ll a,ll p){returnqpow(a,p-2,p);}
ll dp[MAX],dp2[MAX];
ll p[MAX],w[MAX];intmain(){
IOS;int n;cin >> n;
ll sum =0;for(int i =1;i <= n;++i){
cin >> w[i];
sum += w[i];}for(int i =1;i <= n;++i){
p[i]= w[i]*inv(sum)% MOD;}
ll ans =0;for(int i = n;i >=1;--i){
ll fz = p[i];for(int j = i +1;j <= n;++j){
fz =(fz + p[j]*(dp[j]+1)% MOD)% MOD;}for(int j =1;j < i;++j){
fz =(fz + p[j]*(1))% MOD;}
ll fm =(1- p[i]+ MOD)% MOD;
dp[i]= fz *inv(fm)% MOD;}for(int i = n;i >=1;--i){
ll fz =(p[i]*2% MOD * dp[i]% MOD + p[i])% MOD;for(int j = i +1;j <= n;++j){
fz =(fz + p[j]*(dp2[j]+2LL* dp[j]% MOD +1)% MOD)% MOD;}for(int j =1;j < i;++j){
fz =(fz + p[j]*(1)% MOD)% MOD;}
ll fm =(1- p[i]+ MOD)% MOD;
dp2[i]= fz *inv(fm)% MOD;
ans =(ans +(dp2[i]+2* dp[i]+1)% MOD * p[i]% MOD)% MOD;}
cout << ans << endl;return0;}