括號序列 dp Gosling

2021-09-29 02:27:07 字數 4125 閱讀 1024

【題目描述】

描述多年前 lyra 在 evan 的壁爐裡發現了一棵樹,這棵樹非常奇特,它貼著壁爐的內壁生長,汲取火焰中的魔法元素給自己提供養分,善於記憶的 lyra 記下了當時樹的形態。

當年年幼無知的 lyra 還不知道 evan 家這棵樹具有靈性,繼續生長下去有著無盡的潛力和價值。如今 lyra 又站在 evan 的壁爐旁,發現 evan 家的這棵樹已經長了不少,作為 lyra 的好朋友, evan 告訴 lyra,這棵靈樹生長需要 evan 投入魔法石到火焰中,而它生長過程也十分奇特:

這棵樹可以抽象成一棵帶邊權的有根樹,由於生長在牆壁上,每個節點的所有孩子節點之間是有相對順序的(可以假設為從左至右),此外樹還有兩個屬性 c1,c2,樹的生長包含四種變化:

生長: 對於樹的乙個節點 x,考慮其孩⼦節點 y1,y2,⋯,ym,從 x 上長出乙個新節點 z 插入到其孩子中第 k 個位置,於是 x 的孩子節點序列變成了 y1,y2,⋯,yk−1,z,yk,yk+1⋯,ym。 將 的權值設為 w 的消耗為 c1w 單位魔法石。

伸展: 對於樹的乙個節點 x,考慮其孩子節點 y1,y2,⋯,ym,選取乙個區間 [l,r](1≤l≤r≤m),從 x 上長出乙個新節點 z 作為 yl,yl+1,⋯,yr 的父親。此時 x 的孩子序列為y1,y2,⋯,yl−1,z,yr+1,⋯,ym, z 的孩子序列為 yl,yl+1,⋯,yr。並且對於 l≤i≤r,邊 就是原樹上的邊 。將 的權值設為 w 的消耗為 c1w 單位魔法石。

收縮: 對於樹的乙個節點 x,考慮其孩子節點 y1,y2,⋯,ym,選取其乙個孩子節點 yk,令其孩子序列為 z1,z2,⋯,zp,將 縮掉(即去掉 yk,並將 yk 的所有孩子保持順序接到yk 原來在 x 孩子中的位置)。此時 x 的孩子序列為 y1,y2,⋯,yk−1,z1,z2,⋯,zp,yk+1,⋯,ym。並且對於 1≤i≤p,邊 就是原樹上的邊 。令 w 等於原樹上 的權值,則此操作需要消耗 c1w 單位魔法石。

轉化: 對於樹上乙個節點 x 和其某個孩子 y,保持 y 在 x 的孩子序列中位置不變,把的權值從 w1(現有權值)修改為 w2,需要消耗 c2∣w1−w2∣ 單位的魔法石。

注意:第四種操作使用的魔法與前三種操作有所不同,所以由操作「生長」和「伸展」生成的邊無法繼續參與「轉化」,同時「轉化」過的邊無法被「收縮」。

lyra 知道魔法石是一種貴重的資源,很少有人能這樣燒著玩,為了弄清楚 evan 究竟有多富有,她想通過樹的形態變化來確定這些年 evan 至少花費了多少魔法石。

現在給出 lyra 小時候樹的形態與邊權,和現在樹的形態與邊權,求由如上四個操作把樹做如此變化的最小消耗。

兩棵樹被認為是相同當且僅當存在乙個編號的對映,使得在該對映下一棵樹與另一棵樹的邊,每個節點的孩子順序,以及對應邊權都完全相同,且根保持不變。

n

1<=50

,n

2<

=2000

n_1<=50,n_2<=2000

n1​<=5

0,n2

​<=2

000毒瘤題。注意到生長伸展和收縮互為逆操作,我們可以把在一棵樹上生長伸展和收縮,等價地變為在兩棵樹上同時收縮。暴力即2

n2^n

2n列舉每條邊是否收縮。考慮括號序列,那麼收縮意味著刪除一對括號,轉化意味著改變一對括號的權值,那麼問題轉化成了給定兩個括號序列,問使這兩個括號序列匹配的最小代價。定義fl,

r,x,

yf_

fl,r,x

,y​表示第一棵樹的括號序列的區間[l,r]和第二顆樹的區間[x,y]匹配的最小代價。一對括號沒有被刪除當且僅當左右括號都沒有被刪除。所以轉移時我們可以從左到右考慮每個左括號,跳過右括號(右括號所在括號對已被刪除)。轉移時考慮三種情況:1.刪除第一棵樹的左括號。2.刪除第二顆樹的左括號。3.通過轉化使兩個左括號匹配。時間複雜度o(n

12n2

2)

o(n_1^2n_2^2)

o(n12​

n22​

)。考慮優化,對於一段正在考慮的區間,括號序列形如:

( ..

.)(.

..).

..(.

..)(

...)

(...)(...)...(...)(...)

(...)(

...)

...(

...)

(...

)為了盡量避開第二顆樹的重兒子,我們可以比較最左端括號和最右端括號的大小,只考慮刪除小一點的那個括號的左(右)括號。轉移時跳過另一半已被刪除的左右括號即可。可以證明,第二顆樹的轉移時間複雜度為o(∑

size

輕兒子)

=o(n

2log

n2

)o(\sum size_)=o(n_2logn_2)

o(∑siz

e輕兒子

​)=o

(n2​

logn

2​),第一棵樹轉移時間複雜度o(n

12

)o(n_1^2)

o(n12​

)。總時間複雜度為o(n

12n2

logn

2)

o(n_1^2n_2logn_2)

o(n12​

n2​l

ogn2

​)

#include

#define re register

using

namespace std;

const

int n=

1e5+

5,mod=

19260817

;inline

intred()

typedef

long

long ll;

int n[2]

,a,b;ll c1,c2;

ll g[mod]

,vis[mod]

;struct nodee[2]

[n];

int f[2]

[n],nxp[2]

[n],cnt[2]

,d[2

][n]

,st[2]

[n],ed[2]

[n],tot[2]

;const ll h1=

103*

103,h2=

103*

103*

4003

;inline ll hash

(const

int&l,

const

int&r,

const

int&x,

const

int&y)

inline

intfind

(int l,

int r,

int x,

int y)

inline

void

add(

const

int&u,

const

int&v,

const

int&w,

const

int&t)

;nxp[t]

[cnt[t]

]=f[t]

[u];f[t]

[u]=cnt[t];}

void

dfs(

int u,

const

int&t)

}void

init

(const

int&t)

int*d1=d[0]

,*st1=st[0]

,*ed1=ed[0]

;int

*d2=d[1]

,*st2=st[1]

,*ed2=ed[1]

;node*e1=e[0]

,*e2=e[1]

;inline

void

cmin

(ll&x,

const ll&y)

ll dp

(int l,

int r,

int x,

int y)

if(ed2[d2[x]

]-st2[d2[x]

]<=ed2[d2[y]

]-st2[d2[y]])

else

}signed

main()

括號序列(棧)

定義滿足以下規則字串為規則序列,否則不是規則序列 1 空序列是規則序列 2 如果s是規則序列,那麼 s s 和也是規則序列 3 如果a和b都是規則序列,那麼ab也是規則序列。例如,下面的字串都是規則序列 而以下幾個則不是 現在,給你一些由 構成的字串,請判斷該字串是否為規則序列。第一行 乙個正整數n...

合法括號序列

合法括號序列 鍵盤上有左括號 右括號 和退格鍵 共三個鍵。牛牛希望按鍵n次,使得輸入的字串恰好乙個合法的括號序列。每按一次左括號 字串末尾追加乙個左括號 每按一次右括號 字串末尾追加乙個右括號 每按一次退格鍵 會刪掉字串的最後乙個字元,特別的,如果字串為空,牛牛也可以按退格,但是什麼都不會發生。輸出...

2058 括號序列

時間限制 2 s 空間限制 128000 kb 題目等級 silver 題解檢視執行結果 description 定義滿足以下規則字串為規則序列,否則不是規則序列 1 空序列是規則序列 2 如果s是規則序列,那麼 s s 和也是規則序列 3 如果a和b都是規則序列,那麼ab也是規則序列。例如,下面的...