# poj1141 括号序列 dp

dp[ i ][ j ] 存储 i～j 这段括号序列需要添加的括号数，决策有两种，对dp[ i ][ j ],

(1).若i 与j 是匹配的，只需将i+1~j-1这段变成合理的括号序列；

(2).取i～j中间的k， 使i~p 和 p+1~j 均为合理的括号序列。

#include <iostream>
#include <string>
using namespace std;

const int M = 105;

char str[M];
int dp[M][M];
string ans[M][M];

int Search(int l, int r)
{
int i, min = 10000000;

if(dp[l][r] != -1) return dp[l][r];
if(l > r) return 0;
if(l == r) {
if(str[l] == '(' || str[l] == ')') ans[l][r] = "()";
else ans[l][r] = "[]";
return dp[l][r] = 1;
}

int mark = 0, tmp;
int id;
for(i = l; i < r; i++){
tmp = Search(l, i) + Search(i+1, r);
if(tmp < min){
id = i;
min = tmp;
mark = 2;
}
}
if(( str[l] == '(' && str[r] == ')' ) || ( str[l] == '[' && str[r] == ']' ) ){
tmp = Search(l+1, r-1);
if(min > tmp) {
min = tmp;
mark = 1;
}
}
if(mark == 1) ans[l][r] = str[l]+ans[l+1][r-1]+str[r];
else ans[l][r] = ans[l][id]+ans[id+1][r];

return dp[l][r] = min;
}
int main()
{
int i, j;
memset(dp, -1, sizeof(dp));
cin >> str+1;
int len = strlen(str+1);
for(i = 1; i <= len; i++)
for(j = i; j <= len; j++)
ans[i][j] = ans[j][i] = "";
Search(1, len);
cout << ans[1][len] << endl;
//system("pause");
return 0;
}

#include <iostream>
using namespace std;

#define M 105

int dp[M][M], path[M][M];
char str[M];
int n;

void output(int i, int j)
{
if(i == j){
if(str[i] == '(' || str[i] == ')')
printf("()");
else printf("[]");
return;
}
if(path[i][j] == -1){
if(i+1 == j)
printf("%c%c", str[i], str[j]);
else{
printf("%c", str[i]);
output(i+1, j-1);
printf("%c", str[j]);
}
}
else{
output(i, path[i][j]);
output(path[i][j]+1, j);
}
}

int main()
{
int i, j, l, k;

gets(str);
n = strlen(str);
if(n == 0) {
printf("\n");
return 0;
}
for(l = 1; l <= n; l++){
for(i = 0; i+l-1 < n; i++){
j = i+l-1;
if(i == j) dp[i][j] = 1;
else {
dp[i][j] = INT_MAX;
if( (str[i] == '(' && str[j] == ')') || (str[i] == '[' && str[j] == ']') ){
if(i+1 == j) dp[i][j] = 0;
else {
if(dp[i][j] > dp[i+1][j-1])
dp[i][j] = dp[i+1][j-1];
}
path[i][j] = -1;
}
for(k = i; k < j; k++)
if(dp[i][j] > dp[i][k]+dp[k+1][j]){
dp[i][j] = dp[i][k]+dp[k+1][j];
path[i][j] = k;
}
}
}
}
output(0, n-1);
printf("\n");
// system("pause");
return 0;
}


• 本文已收录于以下专栏：

举报原因： 您举报文章：poj1141 括号序列 dp 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)