括号匹配
题意:
有一串字符,就是两种括号组成,当然现在是没有匹配完全,问怎么匹配才能使得添加的括号最少!
思路:
首先括号并不一定是直接在最后添加才好,根据样例就可以看出,所以需要分区间,可是怎么分区间呢?
区间的分法肯定是从小到大分,区间分好的时候该怎么判断?
定义:
dp[i][j]表示字符串的第i个到第j个匹配之后最少的次数,若要想得到最少肯定是分情况,当s[i] = s[j]的时候,
dp[i][j]=dp[i−1][j−1]当不同的时候就分区间,当然即使相同也要在i与j之间找到有没有更少的次数。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
int const INF = 0xfffffff;
int n;
char s[maxn];
int dp[maxn][maxn];
int path[maxn][maxn];
void dfs(int i,int j)
{
if(i > j) return ;
else if(i == j) {
if(s[i] == '(' || s[i] == ')')
printf("()");
else
printf("[]");
}
else if(path[i][j] == -1) {
printf("%c",s[i]);
dfs(i+1,j-1);
printf("%c",s[j]);
}
else {
dfs(i,path[i][j]);
dfs(path[i][j] + 1,j);
}
}
int main(int argc, char const *argv[])
{
//freopen("in.txt","r",stdin);
while(gets(s)) {
int n = strlen(s);
if(n == 0) {
printf("\n");
continue;
}
memset(dp,0,sizeof(dp));
memset(path,0,sizeof(path));
for(int i = 0;i < n; i++)
dp[i][i] = 1;
for(int l = 1;l < n; l++) {
for(int i = 0;i < n-l; i++) {
int j = i + l;
dp[i][j] = INF;
if((s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']')) {
dp[i][j] = dp[i+1][j-1];
path[i][j] = -1;
}
for(int 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;
}
}
}
}
dfs(0,n-1);
printf("\n");
}
return 0;
}