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

来源:互联网 发布:vb picturebox 清空 编辑:程序博客网 时间:2024/05/21 21:18

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 LOCALusing 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!


0 0
原创粉丝点击