NYOJ 题目15 括号匹配(二)(区间DP)

点我看题目

题意 : 中文题不详述。

思路 : 本来以为只是个小模拟,没想到是个区间DP,还是对DP不了解。

DP[i][j]代表着从字符串 i 位置到 j 位置需要的最小括号匹配。

所以初始化的DP[i][i] = 1 ;第i个位置的话需要匹配的最小括号数是1。

状态转移方程 :如果第i个位置和第j个位置的两个括号是匹配的,那么DP[i][j] = DP[i+1][j-1],相当于两边分别往里缩了一个;当i < j 时,DP[i][j] = DP[i][k]+DP[k+1][j] ;

黑书上对于这个问题有详细的解释。我用的就是黑书上的方法二,不过方法二有点赘余,就是我代码中注释的部分,加上也对,不加也可。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 
 5 using namespace std ;
 6 
 7 int dp[210][210] ;
 8 char ch[123] ;
 9 
10 int main()
11 {
12     int n ;
13     scanf("%d",&n) ;
14     getchar() ;
15     while(n--)
16     {
17         scanf("%s",ch);
18         memset(dp,0,sizeof(dp)) ;
19         int len = strlen(ch) ;
20         for(int i = 0 ; i < len ; i++)
21             dp[i][i] = 1 ;
22         for(int h = 1 ; h < len ; h++)
23         {
24             for(int i = 0 ; i < len-h ; i++)
25             {
26                 int j = h+i ;
27                 dp[i][j] = 99999999 ;
28                 if((ch[i] == '('&&ch[j] == ')') || (ch[i] == '[' && ch[j] == ']'))
29                 dp[i][j] = min(dp[i][j],dp[i+1][j-1]) ;
30 //                else if(ch[i] == '(' || ch[i] == '[')
31 //                        dp[i][j] = min(dp[i][j],dp[i+1][j])+1 ;
32 //                else if(ch[j] == ')' || ch[j] == ']')
33 //                    dp[i][j] = min(dp[i][j],dp[i][j-1])+1 ;
34                 for(int k = i ; k <= j ; k++)
35                     dp[i][j] = min(dp[i][j],dp[i][k-1]+dp[k][j]) ;
36             }
37         }
38         printf("%d
",dp[0][len-1] ) ;
39     }
40     return 0 ;
41 }
View Code
原文地址:https://www.cnblogs.com/luyingfeng/p/3659481.html