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\n",dp[0][len-1] ) ;

39     }

40     return 0 ;

41 }
View Code

 

 

你可能感兴趣的:(dp)