#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#define M 105
using namespace std;
const int inf = 0x13131313;
char s[M];
int dp[M][M] = {0};
int record[M][M];
int Min(int a,int b){return a>b?b:a;}
void print(int i,int j)
{
if(i > j) return ;
if(i == j)
{
if(s[i] == '(' || s[i] == ')') printf("()");
if(s[i] == '[' || s[i] == ']') printf("[]");
return ;
}
if(record[i][j] == -1)
{
printf("%c",s[i]);
print(i+1,j-1);
printf("%c",s[j]);
}
else
{
print(i,record[i][j]);
print(record[i][j]+1,j);
}
}
int main()
{
scanf("%s",s);
int index;
int n = strlen(s);
for (int i = 0; i < n; ++i)
dp[i][i] = 1;
memset(record,inf,sizeof(record));
for (int i = 1; i <= n-1; ++i) //间隔为1
{
for (int j = 0; j < n-i; ++j)
{
index = j + i;
dp[j][index] = inf;
/*
其实,才开始这个想法就是看的矩阵连乘的dp规划。
这题,我一直觉得有个弯子,比较难转过来,
看了黑书,才慢慢明白了,
dp[j][index] = Min(dp[j][index],dp[j+1][index-1]);
比如dp[1][2] = Min(dp[1][2],dp[2][1]);
发现才开始没有在dp[2][1]做了计算。不过这种情况,dp[1][2]=0;
所以说,dp[i+1][i]=0;所以才开始的时候对dp数组赋值只对dp[i][i]赋值。
*/
if((s[j] == '(' && s[index] == ')') || (s[j] == '[' && s[index] == ']'))
{
record[j][index] = -1;
dp[j][index] = Min(dp[j][index],dp[j+1][index-1]);
}
for (int k = j; k < index; ++k)
{
if(dp[j][k] + dp[k+1][index] < dp[j][index])
{
dp[j][index] = dp[j][k] + dp[k+1][index];
record[j][index] = k;
}
}
}
}
print(0,n-1);
printf("\n");
return 0;
POJ 1141
最新推荐文章于 2014-05-09 22:50:10 发布