POJ 1141 Brackets Sequence(区间DP + 打印路径)

题意:

寻找一种正确的括号匹配方案,并且打印出来。

思路:

1. 转移方程为:dp[i][j] = min(dp[i][k] + dp[k+1][j]); 如果 s[i] == s[j] 则还有 dp[i][j] = min(dp[i][j], dp[i+1][j-1]);

2. 因为涉及到打印路径,所以还要单独开辟一个数组出来,记录每次选择的结果。这也差不多是打印路径一类题定势的解题步骤;

 

#include <iostream>

#include <algorithm>

using namespace std;



const int MAXN = 110;

const int INFS = 0x3fffffff;

char s[MAXN];

int dp[MAXN][MAXN], choose[MAXN][MAXN];



void printstring(int i, int j) {

    if (i > j)

        return;



    if (i == j) {

        if (s[i] == '(' || s[i] == ')')

            printf("()");

        else

            printf("[]");

    } else if (choose[i][j] == -1) {

        printf("%c", s[i]);

        printstring(i + 1, j - 1);

        printf("%c", s[j]);

    } else {

        printstring(i, choose[i][j]);

        printstring(choose[i][j] + 1, j);

    }

}



int main() {

    while (gets(s)) {

        int len = strlen(s);

        for (int i = 0; i < len; i++)

            dp[i][i] = 1, dp[i+1][i] = 0;



        for (int p = 1; p < len; p++) {

            for (int i = 0, j = i + p; j < len; i++, j++) {

                dp[i][j] = INFS;

                choose[i][j] = -1;



                if ((s[i] == '(' && s[j] == ')') ||

                    (s[i] == '[' && s[j] == ']'))

                    dp[i][j] = min(dp[i][j], dp[i+1][j-1]);

                

                for (int k = i; k < j; k++) {

                    if (dp[i][j] > dp[i][k] + dp[k+1][j]) {

                        choose[i][j] = k;

                        dp[i][j] = dp[i][k] + dp[k+1][j];

                    }

                }

            }

        }

        printstring(0, len - 1);

        printf("\n");

    }

    return 0;

}

你可能感兴趣的:(sequence)