括號匹配(POJ2955)題解

2022-05-09 19:58:05 字數 1308 閱讀 9582

題目大意:給出一串括號,求其中的最大匹配數。

我這麼一說題目大意估計很多人就蒙了,其實我看到最開始的時候也是很蒙的。這裡就來解釋一下題意。

這道題讓求的是最大常規匹配數,什麼是常規匹配呢?

()    ()  ()  [()]都是常規序列。

翻譯一下題目的英文:

我們給出了「常規括號」序列的以下歸納定義:

樣例輸入

((()))

()()()

(]))[)(

([)end

樣例輸出

664

06

現在開始說思路。

很明顯,這是一道區間dp,因為大的常規括號一定是包含小的常規括號的,滿足我們區間dp的要求。

區間dp常用列舉方式見

首先是狀態,非常簡單,dp[i][j]表示從i到j的最大匹配數,我們要求的答案就是dp[1][n]

我們開始列舉,假如我們列舉到的[i][j]中,第i個和第j個是匹配的括號,即()或者[ ]

那麼dp[i][j]=dp[i+1][j-1]+2;

沒錯吧,我們只需要在原基礎上+2就好了。

如果[i] 和[j]不匹配呢?

那我們可以把這個區間分為兩段,以k為分界點。

分成[i][k],[k+1][j]兩段,然後把兩段的值相加就好了。因為這兩個括號不匹配,不代表其中的不匹配。人不能在一棵樹上吊死。

需要注意的是,即使是[i]和[j]兩個括號匹配,仍需列舉k來判斷是否可以將這個區間分成兩段,因為這樣得到的仍然可能不是最優解。

例如:()()這個序列。

顯然答案應該為4,但是最左面和最右面匹配,而中間 ")("

#include#include

#include

#include

using

namespace

std;

char a[105

];int dp[105][105

];int

main()

int n =strlen(a);

memset(dp,

0,sizeof

(dp));

for(int len = 2;len<=n;len++)

for(int k = i;k<=j;k++)

}

}printf(

"%d\n

",dp[0][n-1

]); }

return0;

}

poj2955(括號匹配DP)

題意 給乙個由 四種字元任意排列組成的字串,求最長合法的不連續字串的長度。思路 dp的時候有點倍增的意思,算出來以每個位置開始任意長度內的答案。倍增著算,注意計算一段的時候先判斷兩頭是否可以匹配,然後再列舉分界點來繼續鬆弛。關鍵給的字串不超過100,資料太弱了 n 3 的複雜度。include in...

POJ 2955 括號匹配,區間DP

題意 給你一些括號,問匹配規則成立的括號的個數。思路 這題lrj的黑書上有,不過他求的是新增最少的括號數,是的這些括號的匹配全部成立。我想了下,其實這兩個問題是一樣的,我們可以先求出括號要匹配的最少數量,那麼設原來括號的數量為l 新增了l 那麼其實原來括號匹配成功的括號數就是 l l 2 l 2。d...

poj2955 括號匹配,區間dp

題目大意 給乙個由,組成的字串,其中 可以匹配,求最大匹配數 題解 區間dp dp i j 表示區間 i,j 中的最大匹配數 初始狀態 dp i i 1 i,i 1可以匹配 2 0 狀態轉移見 include include include include include include using...