poj2955 (区间dp)

来源:互联网 发布:天庭淘宝店txt下载无常 编辑:程序博客网 时间:2024/05/22 08:18

点击打开链接

/*translation:给定一对括号序列,要求其中已经配对的括号数量(不是对数)。solution:区间dpd[i][j]表示i~j的最优解。当s[i]配对s[j]时,分两大类情况。第一类是首尾两个配对,然后再加上中间的。第二类是s[i]可能与i~j的中间某个括号k配对。此时最优解就是i~k的最优解加上k~j的最优解。当s[i]不配对s[j]时,也分为两大类。第一种是i~j-1和i+1~j中两个最优解选最大的。第二类情况和s[i]配对s[j]时的第二类情况一样。note:1:区间dp解决这类首位配对问题时候不能简单模仿按照lcs的转移方程来。因为其中会漏掉中间的一些情况,所以要具体问题具体分析。2:首位配对类似的问题可以参照此题的解法。date:2016.9.1*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 101;char s[maxn];int d[maxn][maxn];inline bool match(char a, char b) {if(a == '(' && b == ')')return true;if(a == '[' && b == ']')return true;return false;}int main(){//freopen("in.txt", "r", stdin);    while(~scanf("%s", s) && s[0] != 'e') {memset(d, 0, sizeof(d));int len = strlen(s), t;for(int i = len - 1; i >= 0; i--) {for(int j = i + 1; j < len; j++) {t = -1;for(int k = i + 1; k <= j - 1; k++)t = max(t, d[i][k] + d[k + 1][j]);if(match(s[i], s[j]))d[i][j] = max(d[i + 1][j - 1] + 1, t);else {int t2 = max(d[i + 1][j], d[i][j - 1]);d[i][j] = max(t, t2);}}}printf("%d\n", 2 * d[0][len - 1]);    }    return 0;}


0 0