题解 | #括号区间匹配#

括号区间匹配

https://www.nowcoder.com/practice/e391767d80d942d29e6095a935a5b96b

区间dp

dp[i][j]: 区间[i~j]的字符串匹配所插入的字符数最少为dp[i][j]

区间dp,枚举区间长度来遍历i和j。

初始时,区间长度为1时,dp[i][i]=1。长度不为1时,dp[i][j] = inf

当s[i]和s[j]匹配时,dp[i][j] = dp[i+1][j-1]

然后就是枚举区间[i~j]内的分界点,看区间划分的左右两部分的匹配数

#include <iostream>

#include <string.h>
using namespace std;
const int N = 101, inf = 0x3f3f3f3f;
char str[N];
int dp[N][N];
bool check(int l, int r) {
    if ((str[l] == '[' && str[r] == ']') || (str[l] == '(' && str[r] == ')'))
        return true;
    return false;
}
int main() {
    scanf("%s", str + 1);
    int n = strlen(str + 1);
    for (int d = 1; d <= n; d++) {
        for (int l = 1; l + d - 1 <= n; l++) {
            int r = l + d - 1;
            if (d == 1) dp[l][r] = 1; //仅有一个字符时,那最少插入1个字符才匹配
            else {
                dp[l][r] = inf;  
                if (check(l, r))
                    dp[l][r] = min(dp[l][r], dp[l + 1][r - 1]);
                //s[l]与s[r]匹配不匹配都要枚举中间的,比如"[]([]" 明显dp[1][5]=1,如果来自于dp[2][4]("](["-明显是3)就不对了
                for (int k = l; k <= r; k++) {
                    dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r]);
                }
            }
            
        }
    }
    printf("%d", dp[1][n]);
    return 0;
}
// 64 位输出请用 printf("%lld")
#每日一题#
全部评论

相关推荐

已老实求offer😫:有点像徐坤(没有冒犯的意思哈)
点赞 评论 收藏
分享
点赞 1 评论
分享
牛客网
牛客企业服务