UVa #1626 Brackets sequence (例題9-10)

動態規劃的意味還是挺明顯的:如果子結構A、B都ok,則AB也ok。如果Aok,則(A)、[A]也ok。


那麼對於一個序列,我們只要掃描他所有的子結構,取子結構中dp值最小的就好了。邊界條件是1、單獨一個元素,這時因爲無法配對,一定要加上另外一半的括號,因此dp值爲1;2、一對配好對的括號,dp值爲0。


打印解:再次用到了Ideal Path的方法。因爲只用打印任意一組解,找到第一個dp值相同的一對子結構就可以遞歸然後return了。這個return不能忘記,否則會打印出多組解摻雜在一起。


UVa第一百題,再接再厲!


Run Time: 0.985s

#define UVa  "LT9-10.1626.cpp"		//
char fileIn[30] = UVa, fileOut[30] = UVa;

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>

using namespace std;

//Global Variables. Reset upon Each Case!
const int maxn = 100 + 10;
int d[maxn][maxn];
char dummy, s[maxn];
/////

int match(char a, char b) {
    if( (a == '(' && b == ')') || (a == '[' && b == ']')) return 1;
    return 0;
}

void print_ans(int i, int j) {
    if(i == j) printf("%s", (s[i] == '(' || s[i] == ')')?"()":"[]");
    else {
        for(int k = i; k < j; k ++) {
            if(d[i][j] == d[i][k] + d[k+1][j]){
                print_ans(i, k);
                print_ans(k+1, j);
                return;
            }
        }
        if(d[i][j] == d[i+1][j-1]) {
            if(i == j-1) printf("%c%c", s[i], s[j]);
            else {
                printf("%c", s[i]);
                print_ans(i+1, j-1);
                printf("%c", s[j]);
            }
            return;
        }
    }
}

int main() {
    int kase;
    scanf("%d", &kase);
    gets(s);

    while(kase--) {
        gets(s);
        gets(s);
        int n = strlen(s);
        if(n) {
            for(int len = 0; len < n; len ++) {
                for(int i = 0; i+len < n; i ++) {
                    int j = i + len;
                    if(len == 0) d[i][j] = 1;       //single bracket.
                    else {
                        d[i][j] = d[i][i] + d[i+1][j];
                        for(int k = i + 1; k < j; k ++)
                            d[i][j] = min(d[i][j], d[i][k] + d[k+1][j]);
                        if(match(s[i],s[j])) {
                            if(i == j - 1) d[i][j] = 0;
                            else d[i][j] = min(d[i][j], d[i+1][j-1]);
                        }
                    }
                }
            }
            print_ans(0, n-1);
        }
        printf("\n");
        if(kase) printf("\n");
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章