zoukankan      html  css  js  c++  java
  • [codevs3657]括号序列

    题目大意:有一列只有'(',')','[',']'构成的括号序列,求在序列中至少加上多少括号,能使该序列合法。

    解题思路:区间dp。

    我们以$f[i][j]$表示把区间$[i,j]$添成合法括号所需的最小括号数。

    设某段序列为$S_0$,它对应区间为$[i,j]$,括号数为$f[i][j]$.

    若$S_0$形如$(S_1)$或$[S_1]$,$f[i][j]=min{f[i][j],f[i+1][j−1]}$;即令$S_1$合法后,$S_0$可合法。

    若$S_0$形如$(S_1$或$[S_1$,$f[i][j]=min{f[i][j],f[i+1][j]+1}$;即令$S_1$合法后,$S_0$可在最后添加一个括号后合法。

    同理,若$S_0$形如$S_1)$或$S_1]$,

    $f[i][j]=min{f[i][j],f[i][j-1]+1}$;
    无论$S_0$是什么情况,都有$f[i][j]=min{f[i][j],f[i][k]+f[k+1][j]},i≤k<j$;

    即把序列分成两部分分别使其合法。

    这样的时间复杂度为$O(n^3)$。

    注意i要倒着循环,否则可能会出现某些情况还没计算就要使用的情况。

    C++ Code:

    #include<cstdio>
    #include<cstring>
    #define min(a,b) (((a)<(b))?(a):(b))
    char s[120];
    int f[120][120];
    int main(){
    	scanf("%s",s+1);
    	int n=strlen(s+1);
    	memset(f,0,sizeof f);
    	for(int i=1;i<=n;++i){
    		f[i][i]=1;
    		for(int j=i+1;j<=n;++j)f[i][j]=0x3f3f3f3f;
    	}
    	for(int i=n;i;--i){
    		for(int j=i+1;j<=n;++j){
    			if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']')
    			f[i][j]=f[i+1][j-1];
    			if(s[i]=='('||s[i]=='[')
    			f[i][j]=min(f[i][j],f[i+1][j]+1);
    			if(s[i]==')'||s[i]==']')
    			f[i][j]=min(f[i][j],f[i][j-1]+1);
    			for(int k=i;k<j;++k)
    			f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
    		}
    	}
    	printf("%d
    ",f[1][n]);
    	return 0;
    }
    
  • 相关阅读:
    win10 uwp 弹起键盘不隐藏界面元素
    win10 uwp 存放网络图片到本地
    win10 uwp 存放网络图片到本地
    sublime Text 正则替换
    sublime Text 正则替换
    win10 uwp 绘图 Line 控件使用
    win10 uwp 绘图 Line 控件使用
    AJAX 是什么?
    什么是 PHP SimpleXML?
    PHP XML DOM:DOM 是什么?
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7289480.html
Copyright © 2011-2022 走看看