本文章是[学习笔记]概率与期望进阶的一部分
众所周知,PKUWC/SC是数数和斗地主的天下。
所以这里全是PKU的题:)
PKUSC 2018 最大前缀和
心态崩了啊…感觉这题不简单啊…
小 C 是一个算法竞赛爱好者,有一天小 C 遇到了一个非常难的问题:求一个序列的最大子段和。
但是小 C 并不会做这个题,于是小 C 决定把序列随机打乱,然后取序列的最大前缀和作为答案。
小 C 是一个非常有自知之明的人,他知道自己的算法完全不对,所以并不关心正确率,他只关心求出的解的期望值,现在请你帮他解决这个问题,由于答案可能非常复杂,所以你只需要输出答案乘上 n ! n! n! 后对 998244353 998244353 998244353 取模的值,显然这是个整数。
注:最大前缀和的定义: ∀ i ∈ [ 1 , n ] , ∑ j = 1 i a j \forall i \in [1,n],\sum^{i}_{j=1}a_j ∀i∈[1,n],∑j=1iaj的最大值。
n ≤ 20 n \leq 20 n≤20
首先我们假设最大前缀和的位置是
p
p
p。
根据最大前缀和的性质,我们知道
[
p
+
1
,
n
]
[p+1,n]
[p+1,n]这一段数的所有前缀和都必须
≤
0
\leq 0
≤0否则最大前缀和的性质就不成立。
定义
s
u
m
[
S
]
sum[S]
sum[S]为集合中所有数的权值和。
我们分成两个问题考虑:
- 定义
g
[
S
]
g[S]
g[S]为满足数集为
S
S
S,所有前缀和都必须
≤
0
\leq 0
≤0的方案数。
转移很简单 g [ S ] + = g [ S − i ] ( s u m [ S ] ≤ 0 ) g[S]+=g[S-i](sum[S]\leq 0) g[S]+=g[S−i](sum[S]≤0)。 - 对于前缀来说,我们必须满足
s
u
m
[
S
]
sum[S]
sum[S]就是最大前缀和。考虑从
p
p
p往
1
1
1计算方案。每次我们在前面加一个数,首先根据最大前缀和的定义,这个数我们必须选,但后面的数我们可以做决定,显然只有在
s
u
m
[
S
]
>
0
sum[S]>0
sum[S]>0的时候才会选择保留后面的一段数。
定义 f [ S ] f[S] f[S]表示数集为 S S S,满足 s u m [ S ] sum[S] sum[S]就是最大前缀和的方案数。
转移: f [ S + i ] + = f [ S ] ( s u m [ S ] > 0 ) f[S+i]+=f[S](sum[S]>0) f[S+i]+=f[S](sum[S]>0)。
最终的答案就是
s
u
m
[
S
]
⋅
f
[
S
]
⋅
g
[
U
−
S
]
sum[S]·f[S]·g[U-S]
sum[S]⋅f[S]⋅g[U−S](其中
U
U
U表示全集)。
复杂度:
O
(
2
n
n
)
O(2^n n)
O(2nn)
PKUWC2018 随机算法
比较简单的一道题。
给你一个算法:
- 对于一个 n n n 个点的无向图,先等概率随机一个 1... n 1...n 1...n 的排列 p [ 1... n ] p[1...n] p[1...n]。
- 维护答案集合 S S S ,一开始 S S S 为空集,之后按照 i = 1... n i=1...n i=1...n 的顺序,检查 p [ i ] ∪ S {p[i]}∪S p[i]∪S 是否是一个独立集,如果是的话就令 S = p [ i ] ∪ S S={p[i]}∪S S=p[i]∪S。
- 最后得到一个独立集 S S S作为答案。
小 C 现在想知道,对于给定的一张图,这个算法的正确率,输出答案对 998244353 998244353 998244353 取模。
n ≤ 20 n\leq 20 n≤20
首先
30
30
30分暴力做法是
d
p
[
S
]
[
T
]
dp[S][T]
dp[S][T]表示现在选了集合
S
S
S,其中最大独立集为
T
T
T的方案数。
复杂度是
O
(
n
3
n
)
O(n3^n)
O(n3n)的。
然后我们发现其实只要我们选出了
T
T
T,我们的
S
S
S就没有存在的必要了,因为之后无论如何都没有办法将
S
−
T
S-T
S−T中的数加进去了。
所以我们直接定义
d
p
[
T
]
dp[T]
dp[T]表示最大独立集为
T
T
T的方案数。
每次枚举一个点并将不与其冲突的点加进去。
复杂度
O
(
n
2
2
n
)
O(n^22^n)
O(n22n)。
如果我们把图存成一个状态进行位运算就是
O
(
n
2
n
)
O(n2^n)
O(n2n)的了。
PKUWC2018 猎人杀
很综合的一道题目…
猎人杀是一款风靡一时的游戏“狼人杀”的民间版本,他的规则是这样的:
一开始有 n n n 个猎人,第 i i i 个猎人有仇恨度 w i w_i wi ,每个猎人只有一个固定的技能:死亡后必须开一枪,且被射中的人也会死亡。
然而向谁开枪也是有讲究的,假设当前还活着的猎人有 [ i 1 , . . . , i m ] [i_1,...,i_m] [i1,...,im],那么有 w i k ∑ j = 1 m w i j \frac{w_{i_{k}}}{\sum^{m}_{j=1}w_{i_j}} ∑j=1mwijwik 的概率是向猎人 i k i_k ik 开枪。
一开始第一枪由你打响,目标的选择方法和猎人一样。由于开枪导致的连锁反应,所有猎人最终都会死亡,现在 1 1 1 号猎人想知道它是最后一个死的的概率。
答案对 998244353 998244353 998244353 取模。
∑ w i ≤ 100000 \sum w_i\leq 100000 ∑wi≤100000
这题和上一道题的核心思想其实是一样的。
我们其实可以发现,如果一个猎人集合
S
S
S被限定为存在猎人先被1
杀,那么每个猎人不管死没死,都可以作为攻击目标,这样算概率是相等的。因为我们既完成了目标,又没有次数限制。
所以我们考虑容斥,设
S
S
S为限制在1
后被杀的猎人:
∑
S
(
−
1
)
∣
S
∣
p
(
S
)
\sum_{S}(-1)^{|S|}p(S)
S∑(−1)∣S∣p(S)
接下来我们来计算
p
(
S
)
p(S)
p(S):
设
A
=
∑
w
i
A=\sum w_i
A=∑wi,
B
=
∑
i
∈
S
w
i
B=\sum_{i\in S}w_i
B=∑i∈Swi。
那么有:
p
(
S
)
=
A
−
B
−
w
1
A
p
(
S
)
+
w
1
A
p(S)=\frac{A-B-w_1}{A}p(S)+\frac{w_1}{A}
p(S)=AA−B−w1p(S)+Aw1
解方程得:
p
(
S
)
=
w
1
B
+
w
1
p(S)=\frac{w_1}{B+w_1}
p(S)=B+w1w1
因此有:
∑
S
(
−
1
)
∣
S
∣
w
1
B
+
w
1
\sum_{S}(-1)^{|S|}\frac{w_1}{B+w_1}
S∑(−1)∣S∣B+w1w1
题目只限制了
∑
w
i
\sum w_i
∑wi。
所以我们按照套路,背包dp计算
B
B
B相同的系数和。
然而这样是
O
(
A
2
)
O(A^2)
O(A2)的。
考虑生成函数:
∏
i
=
1
n
(
1
−
x
w
i
)
\prod^n_{i=1}(1-x^{w_i})
i=1∏n(1−xwi)
所以分治+NTT即可。
复杂度:
O
(
A
log
2
A
)
O(A\log^2 A)
O(Alog2A)。
还有一些题目:
PKUSC 2018 PKUSC
PKUSC 2018 随机游走