UVA 1626 Brackets sequence dp:经典&&类似于三角剖分

UVA - 1626
Brackets sequence
Time Limit: 4500MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

Submit Status


The question is from here.


My Solution

类似于 triangulation 三角剖分的dp经典

如果是[。。]或(。。)这样的向里面转移 dp[ i ][ j ] = min(dp[ i [ j ], dp[ i+1 ][ j-1 ]);

如是是不同的则开始找点k ,必然存在一个k,使得 i - k - j得到一个最小值,即 d[ i ][ j ] = min(d[ i ][ j ], d[ i ][ k ]+d[ k+1 ][ j ];


边界: 为空是 d[ i ][ j ] = 0; (i > j)    转移的时候如果到了 i,i+1 再往里转移一次就 i+1,i 了  也就是这是如果为情况1则d[ i ][ j ] =0;

    或者为单个字符 d[ i ][ j ] = 1;(i == j) 


打印:再算出最优的地方 1、如果可以直接往里转移,则 d[ i ][ j ] == d[ i+1 ][ j-1 ];把这个打印了,再向里递归;

                                         2、如果是情况2则直接去找那个k进行切分,然后递归


#include <iostream>
#include <cstdio>
#include <cstring>
//#define LOCAL
using namespace std;
int d[104][104],n;
char s[104];
bool match(char a, char b)
{
    if(a == '(' && b == ')') return true;
    if(a == '[' && b == ']') return true;
    return false;
}
void dp()
{
    for(int i = 0; i < n; i++) {
        d[i+1][i] = 0;
        d[i][i] = 1;
    }
    for(int i = n-2; i >= 0; i--){
        for(int j = i+1; j < n; j++){
            d[i][j] = n;
            if(match(s[i],s[j])) d[i][j] = min(d[i][j],d[i+1][j-1]);
            for(int k = i; k < j; k++)
                d[i][j] = min(d[i][j],d[i][k]+d[k+1][j]);
        }
    }
}

void print(int i, int j)
{
    if(i > j) return;
    if(i == j){
        if(s[i] == '(' || s[i] == ')') printf("()");
        else  printf("[]");
        return;
    }
    int ans = d[i][j];
    if(match(s[i],s[j]) && ans == d[i+1][j-1]){
        printf("%c", s[i]);print(i+1,j-1);printf("%c", s[j]);
        return;
    }
    for(int k = i; k < j; k++){
        if(ans == d[i][k]+d[k+1][j]){
            print(i,k);print(k+1,j);
            return;
            //即使有多个情况也只要打印一种,一般是选第一种或最后一种吧
            //重写前,也就是最开始写这里的if子块掉了一对大括号,重写AC后又找了好久,才找出来这个bug
        }
    }
}

int main()
{
    #ifdef LOCAL
    freopen("a.txt","r",stdin);
    #endif // LOCAL
    int T;
    scanf("%d", &T);getchar();
    while(T--){
        gets(s);
        gets(s);
        n = strlen(s);
        dp();
        print(0,n-1);
        printf("\n");
        if(T) printf("\n");

    }

    return 0;
}


最开始写的一直WA,后来实在不行了,重写吧,重写了就AC,然后对着找找bug又找了好久,真是迷啊


警察叔叔就是他  \__/



Thank you!


你可能感兴趣的:(动态规划,ACM,uva,三角剖分,线性结构上的dp)