題解 括號染色

2021-10-10 07:25:14 字數 1853 閱讀 9102

petya遇到了乙個關於括號序列的問題:

給定乙個字串s,它代表著正確的括號序列,即(「(」)與 (「)」)是匹配的。例如:「(())()」 和 「()」是正確的,「)()」與「(()」則不是正確的。

在正確的括號序列中,乙個左邊的括號一定是匹配乙個右邊的括號(反之亦然)。例如,在下圖中,第 3 個括號匹配第 6 個括號,第 4 個括號匹配第 5 個括號。

現在你需要對乙個正確的括號序列做塗色操作,嚴格滿足以下三個條件:

每個括號要麼不塗色,要麼塗紅色,要麼塗藍色。

一對匹配的括號需要且只能將其中乙個塗色。

相鄰的括號不能塗上同一種顏色(但是可以都不塗顏色)。

求:給整個括號序列塗上顏色的方案數,答案可能比較大,對 1e9

+71e9+7

1e9+

7 取模。

dp[x][y][i][j]表示 x

xx 到 y

yy 這個區間左端點染 i

ii,右端點染 j

jj 的方案數。首先用棧預處理出每個左端點對應的右端點,然後轉移的時候考慮三種情況:

區間長度為 2

22,這時候列舉 4

44 種染色情況,每種方案都是 111。

match[x]==y時,先處理 x−1

x-1x−

1 到 y−1

y-1y−

1,再根據邊界的染色情況進行轉移。

match[x]!=y時,先分別處理 x

xx 到match[x]match[x]+1到 y

yy,再根據邊界的染色情況進行轉移。

每次遞迴處理的子區間都是合法的括號序列。

#include

#include

#include

#include

using

namespace std;

#define ll long long

const

int maxn=

705;

char s[maxn]

;ll dp[maxn]

[maxn][3

][3]

;//dp[i][j][k][h]表示區間i~j左右端點顏色分別為k,h的情況數

const

int mod=

1e9+7;

int match[maxn]

;//用來儲存互相匹配的括號 match[i]表示與i匹配的括號

void

get(

int l)

else}}

void

**dp

(int a,

int b)

if(match[a]

==b)

if(i!=1)

if(j!=2)

if(i!=2)

}}return;}

//不為匹配的

int t=match[a]

;//從與當前括號匹配那個的開始分割

**dp

(a,t)

;**dp

(t+1

,b);

for(

int i=

0;i<

3;i++)}

}}}}

intmain()

}printf

("%lld"

,ans)

;return0;

}

樹上染色題解

有一棵點數為n的樹,樹邊有邊權。將m個點染成黑色,並將其他的點染成白色。會獲得黑點兩兩之間的距離和加上白點兩兩之間的距離和的收益。問收益最大值是多少。輸入格式 第一行兩個整數n m。接下來n 1行,每行三個整數a b c,表示有一條樹邊連線a b,長度為c。輸出格式 一行 乙個正整數,表示收益的最大...

SDOI2011 染色 題解

題目大意 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點b路徑上的顏色段數量 連續相同顏色被認為是同一段 思路 樹剖之後,維護其兩端的顏色 答案和標記即可。include include define n 100001 using...

題解 括號匹配

題解 描述假設表示式中只包含三種括號 圓括號 方括號和花括號,它們可相互巢狀,如 或 等均為正確的格式,而 或均為不正確的格式.輸入一串括號 如果輸入的右括號多餘,輸出 extra right brackets 如果輸入的左括號多餘,輸出 extra left brackets 如果輸入的括號不匹配...