H-Crystalfly
题目大意
给你一颗树,每个节点都有两个值,一个是权值\(a_i\),还有一个是失效时间\(t_i\)。你一开始在1号节点,如果你在\(t\)时刻走到一个一个点,那么他的所有相邻的点的权值将会在\(t+t_i\)秒末清零。每走到一个点将会采集这个点的权值,问你最多能采集多少权值
解题思路
到达一个节点后,子节点就会立即计时,我们发现\(t_i\)的范围是\(1...3\)我们逐一来考虑\(t_i\)的情况。 * \(t_i=1\),那么如果走到父节点后不立即走到他的话,他的权值就会立即变为0 * \(t_i=2\),可以发现这种情况和\(t_i=1\)等价,因为你从一个兄弟走到这个节点一定来不及。 * \(t_i=3\),从父节点出动,如果你第一秒走到一个兄弟节点,第二秒回头,那么第三秒你还来得及回头来获得这个节点的权值。
我们发现节点可能会返回,但是一旦\(u\)返回到他的父节点,那么他的孩子们将会挂掉。我们dp开三维 \(f[u][t][0/1]\),你在\(t\)时刻访问了\(u\)节点,这个时刻是你从访问父节点时刻到当前时刻的差值,最大为4(因为4以上都没什么意义)。 那么我们开始考虑转移。首先我们考虑需要返回的情况,那么孩子们都会挂掉 \(f(u,t,1)= a_u[t\le t_u]+\sum\limits_{v\in sons(u)}{f(v,4,0)}\) 现在我们开始转移不需要返回的状态。分类讨论,容易知道,我们最多保住两个孩子,但是有的时候只保一个会比较优
- 如果我们只保留一个孩子,我们就找到一个孩子权值最大的加上去就行。\(f(u,t,0)\leftarrow f(u,t,1)+max(a_v)\)
- 如果要保留两个孩子,情况会稍微复杂一点,我们第一步可以先挑一个点走,然后返回父节点,第三步走到一个\(t=3\)的节点上。\(f(u,t,0)\leftarrow \max\limits_{v_1,v_2\in son(u)}{(a_u[t\le t_u]+f(u,1,1)+f(v_1,1,1)-f(v_1,4,0)+f(v_2,3,0))}\)其中\(T_{v_2}=3\),我们用一个multiset维护。见代码
ps: 第二维发现只有两个情况,选和不选
1 |
|