時間限制:
1000 ms | 記憶體限制:65535 kb
難度:6
描述
給你乙個字串,裡面只包含"(",")","[","]"四種符號,請問你需要至少新增多少個括號才能使這些括號匹配起來。
如:是匹配的
()是匹配的
((]是不匹配的
([)]是不匹配的
輸入
第一行輸入乙個正整數n,表示測試資料組數(n<=10)
每組測試資料都只有一行,是乙個字串s,s中只包含以上所說的四種字元,s的長度不超過100
輸出對於每組測試資料都輸出乙個正整數,表示最少需要新增的括號的數量。每組測試輸出佔一行
樣例輸入
4()((]
([)]
樣例輸出
0032
**《演算法藝術與資訊學競賽》
二維陣列dp[i][j] 表示字串s的第i..j字元需要最少括號數,下面是具體的表示:
當i= j的時候,只有乙個字元,那麼,只要匹配乙個字元就行了,所以,dp[i][i] = 1
如果,當i < j的時候,s[i] = s[j] 那麼,dp[i][j] = min(dp[i][j],dp[i+1][j+1]),其中,假設i <= k < j 狀態轉移方程為 dp[i][j] = min(dp[i][j],d[i][k] + dp[k+1][j])
換個角度,換個方向
分析:我們求出這個串的最大匹配,然後串的總長度-最大匹配就是答案。
方法1:首先能想到的是轉化成lcs(最長公共子串行),列舉中間點,求所有的lcs中的最大值 * 2就是最大匹配。但是複雜度較高,光lcs一次就o(n^2)的複雜度。
方法2:
首先考慮怎麼樣定義dp讓它滿足具有通過子結構來求解、
定義dp [ i ] [ j ] 為串中第 i 個到第 j 個括號的最大匹配數目
那麼我們假如知道了 i 到 j 區間的最大匹配,那麼i+1到 j+1區間的是不是就可以很簡單的得到。
那麼 假如第 i 個和第 j 個是一對匹配的括號那麼dp [ i ] [ j ] = dp [ i+1 ] [ j-1 ] + 2 ;
那麼我們只需要從小到大列舉所有 i 和 j 中間的括號數目,然後滿足匹配就用上面式子dp,然後每次更新dp [ i ] [ j ]為最大值即可。
更新最大值的方法是列舉 i 和 j 的中間值,然後讓 dp[ i ] [ j ] = max ( dp [ i ] [ j ] , dp [ i ] [ f ] + dp [ f+1 ] [ j ] ) ;
1 #include 2 #include 34#define min(x,y) (x < y ? x : y)
5#define max 10167
intdp[max][max];89
bool cmp(int n,int
m)10
1617
int main(void)18
31//
區間dp常用dp套路
32for(m = 1; m < length; m++)//
列舉的串長度
3345}46
}47 printf("
%d\n
",dp[0][length-1
]);48}49
return0;
50 }
nyoj 15 括號匹配
時間限制 1000 ms 記憶體限制 65535 kb 難度 6 描述 給你乙個字串,裡面只包含 四種符號,請問你需要至少新增多少個括號才能使這些括號匹配起來。如 是匹配的 是匹配的 是不匹配的 是不匹配的 輸入第一行輸入乙個正整數n,表示測試資料組數 n 10 每組測試資料都只有一行,是乙個字串s...
NYOJ15 括號匹配(二)
題目分析 最開始我想的是用棧來做,結果發現每次求最小不是那麼容易的事情。再說這道題劃分在動態規劃之中也是有它的原因的。這裡用乙個陣列dp來記錄從字串的位置i到位置j至少需要新增的括號數。當然如果i到j只包含乙個字元,那dp i j 一定為1 否則就賦值成乙個比較大的數。如果第i個字元和第j個字元匹配...
nyoj15括號匹配(二)
時間限制 1000 ms 記憶體限制 65535 kb 難度 6 描述 給你乙個字串,裡面只包含 四種符號,請問你需要至少新增多少個括號才能使這些括號匹配起來。如 是匹配的 是匹配的 是不匹配的 是不匹配的 輸入第一行輸入乙個正整數n,表示測試資料組數 n 10 每組測試資料都只有一行,是乙個字串s...