zoukankan      html  css  js  c++  java
  • 括号序列(区间dp)

    括号序列(区间dp)

    输入一个长度不超过100的,由"(",")","[",")"组成的序列,请添加尽量少的括号,得到一个规则的括号序列。如有多解,输出任意一个序列即可。

    括号序列是这样定义而成的:

    • 空序列是括号序列
    • 如果S是括号序列,那么(S)和[S]也是正规括号序列
    • 如果A和B都是正规括号序列,那么AB也是正规括号序列。

    所以,只要一个括号序列不是空序列,我们一定可以把它从两端剥开,或者把它划分成两个小括号序列。设(f[i][j])表示字串(s[i][j])至少要添加几个括号,那么(f[i][j])一定可以转移到(f[i][k]+f[k][j])。如果(s[i]=s[j]),那么也可以转移到(f[i+1][j-1])

    由此可见,区间dp的必要条件是划分后解会不同。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn=105;
    int T, f[maxn][maxn], n;
    char s[maxn];
    
    //函数能使语义更清晰
    bool match(int x, int y){ return s[y]-s[x]>0&&s[y]-s[x]<=2; }
    
    void print(int l, int r){  //[l,r]
        if (l>r) return;
        if (l==r){
            if (s[l]=='('||s[l]==')') printf("()");
            else printf("[]"); return; }
        int ans=f[l][r];
        if (match(l, r)&&f[l+1][r-1]==ans){
            putchar(s[l]); print(l+1, r-1); putchar(s[r]);
            return; }
        for (int k=l; k<r; ++k)
            if (f[l][k]+f[k+1][r]==ans){
                print(l, k); print(k+1, r); return; }
    }
    
    int main(){
        scanf("%d", &T);
        while (T--){
            fgets(s, maxn, stdin);
            fgets(s, maxn, stdin);
            n=strlen(s)-1;
            for (int i=0; i<n; ++i) f[i+1][i]=0, f[i][i]=1;
            for (int i=n-2; i>=0; --i)
                for (int j=i+1; j<n; ++j){
                    f[i][j]=n;
                    if (match(i, j)) f[i][j]=f[i+1][j-1]; //[i,j]
                    for (int k=i; k<j; ++k)
                        f[i][j]=min(f[i][j], f[i][k]+f[k+1][j]);
                }
            print(0, n-1); puts("");
        }
        return 0;  //忘记return 0了!!
    }
    
  • 相关阅读:
    [PATCH] input: add driver for Bosch Sensortec's BMA150 accelerometer
    linux内核GPIO模拟I2C实例
    修改默认apn数据的方法
    Android平台开发WIFI function portingWIFI功能移植
    Silverlight中后台获取样式的方法
    Silverlight中读取Word
    Silverlight找到模板中的子控件
    根据年月来获取该年该月的天数
    Silverlight中Treeview中判断当前节点是否含有父节点
    修改 Linux /etc/profile 以后如何生效
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/8862695.html
Copyright © 2011-2022 走看看