“难度题” 题解
Posted 。✧* ꧁王者꧂✧*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“难度题” 题解相关的知识,希望对你有一定的参考价值。
模拟赛时遇见的一道题,个人感觉这道题忒棒了!
考场时,除了看出来这是道树形
D
P
DP
DP题以外,也就只会打暴力了。
做这道题时,你会发现,直接按原意来
D
P
DP
DP的话,特别麻烦,你得记录每个点所在的连通块的
s
u
m
sum
sum是多少,但因为是
1
e
9
1e9
1e9级别的,这个
D
P
DP
DP状态肯定就不行了。那怎么办呢?既然这样
D
P
DP
DP不行,那就换一种方式
D
P
DP
DP。
若是有经验的
d
a
l
a
o
dalao
dalao们肯定已经发现了。一个联通块的
s
u
m
sum
sum的平方,就相当于在
s
u
m
sum
sum个点中找到两个点
x
,
y
x,y
x,y,
x
x
x涂成红色,
y
y
y涂成蓝色(
x
=
=
y
x==y
x==y是允许的)。这样的话,题意就可以改成:把一个树分成多个连通块,在每个连通块内找两点
x
x
x,
y
y
y分别涂成红色和蓝色的方案数。
D
P
DP
DP状态:
f
[
x
]
[
o
p
]
f[x][op]
f[x][op]表示在
x
x
x为根的子树中,
x
x
x所在的连通块中选了
o
p
op
op个点涂色的方案数。
那么,接下来考虑一下DP方程:
设父亲为
u
u
u,儿子为
v
v
v,初值为:
f
[
x
]
[
0
]
=
1
,
f
[
x
]
[
1
]
=
a
[
x
]
,
f
[
x
]
[
2
]
=
a
[
x
]
∗
a
[
x
]
f[x][0]=1,f[x][1]=a[x],f[x][2]=a[x]*a[x]
f[x][0]=1,f[x][1]=a[x],f[x][2]=a[x]∗a[x]。
然后,用
f
[
v
]
[
0
]
,
f
[
v
]
[
1
]
和
f
[
v
]
[
2
]
来
更
新
f[v][0],f[v][1]和f[v][2]来更新
f[v][0],f[v][1]和f[v][2]来更新,这时候还需要引入一个变量
g
g
g,是用来
D
P
DP
DP转移用的,为了防止被更新过的
f
f
f再次更新其他f值。
DP式子:
for(int j = 0 ;j <= 2 ; j++) //父亲要涂几个
{
for(int k = 0 ; k <= j ; k++)
g[x][j] = (g[x][j] + f[x][j-k] *f[y][k] %p*c[j][k]) %p;//不断边
g[x][j] = (g[x][j] + f[y][2] * f[x][j] %p ) %p;//断边
}
for(int i = 0 ; i <= 2 ; i++)
f[x][i] = g[x][i] , g[x][i] = 0;
上面的式子,一种是当前
u
u
u和
v
v
v之间的边断,一种是之间的边不断,然后,各自转移。然后,这个组合数的存在,是因为你要枚举涂的是哪个颜色,或者说,处理的是红色点在
u
u
u还是在
v
v
v这个问题。
还有一种
D
P
DP
DP形式,不用考虑组合数,状态是:
f
[
u
]
[
0
]
表
示
u
所
在
的
连
通
块
不
涂
色
的
方
案
,
f
[
u
]
[
1
]
表
示
涂
一
个
红
色
点
的
方
案
,
f
[
u
]
[
2
]
表
示
涂
一
个
蓝
色
点
的
方
案
,
f
[
u
]
[
3
]
表
示
红
蓝
两
点
都
涂
的
方
案
f[u][0]表示u所在的连通块不涂色的方案,f[u][1]表示涂一个红色点的方案,f[u][2]表示涂一个蓝色点的方案,f[u][3]表示红蓝两点都涂的方案
f[u][0]表示u所在的连通块不涂色的方案,f[u][1]表示涂一个红色点的方案,f[u][2]表示涂一个蓝色点的方案,f[u][3]表示红蓝两点都涂的方案。
怎么转移呢?
就看你们了。
再见。
以上是关于“难度题” 题解的主要内容,如果未能解决你的问题,请参考以下文章
数据挖掘2022年2023届秋招Kanaries雾角科技算法岗 笔试题
LeetCode155:最小栈,最简单的中等难度题,时间超100%,内存也低于官方
LeetCode155:最小栈,最简单的中等难度题,时间击败100%,内存也低于官方