CF162J Brackets 题解

CF162J Brackets

看到两位用栈匹配括号的大佬,这里提供另一个思路。

对于括号的问题,我们考虑区间DP

设状态 dp[i][j] 表示使区间 [i,j] 内的括号匹配需要添加的括号数量,则转移方程如下:

1 :区间两边括号匹配时,因为最外层不需要匹配,需要添加的括号数量取决于最外层括号内的需要添加的括号数量,也就是 dp[i+1][j1] 的值。

dp[i][j]=min{dp[i][j],dp[i+1][j1]}

2 :枚举分割点 k ,把原区间分 [i,k][k+1,j] 两个区间,然后求和,把使两个子区间需要添加的括号数量合起来,就是总区间需要添加的括号数量。

dp[i][j]=min{dp[i][j],dp[i][k]+dp[k+1][j])}

最后,如果使整个区间的括号匹配不需要任何括号,也就是说 dp[0][n1]=0 ,那么说明这个序列本来就是匹配的,输出 YES ,否则输出 NO

虽然复杂度是 O(n3) ,但是由于序列长度最长只有 100 ,还是可以做的。

C++版本代码如下:

#include <bits/stdc++.h>
using namespace std;
int f[600][600];
char s[600];
int main()
{
    scanf("%s",s);
    int n=strlen(s);
    for(int i=0;i<n;i++)f[i][i]=1;
    for(int l=2;l<=n;l++)
        for(int i=0;i+l-1<n;i++)
            {
                int j=i+l-1;
                f[i][j]=l;
                if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']'))f[i][j]=min(f[i][j],f[i+1][j-1]);
                for(int k=i;k<j;k++)
                    f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]); 
            }
    if(!f[0][n-1])printf("YES"); 
    else printf("NO");
    return 0;
}
posted @   w9095  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示