题目描述:给出一串由‘(‘)’‘ [ ' ' ] '组成的串,让你输出添加最少括号之后使得括号匹配的串。
思路:
i-j表示的是一条序列的开始和结束,dp[ i ][ j ]表示子串s[ i~j ] 需要添加的数量。
思想是不断分割小区间,当出现(X)时,应该转移到x,即从dp(i,j)转移到dp(i+1,j-1)
如果为单个字符,则dp[ i ][ j ] = 1;(i == j)
打印:算出最优的地方 1、如果可以直接往里转移,则 dp[ i ][ j ] == dp[ i+1 ][ j-1 ];把s[i]和s[j]打印了,再向里递归print(i+1, j-1);
2、s[i]!=s[j],则直接去找i-j之间的最优点k进行切分,然后递归
代码:
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
const int inf=0x3f3f3f3f;
string s;
int d[110][110],value[110][110],len;
void print(int i,int j){//递归输出
if(i>j) return;
else if(i==j){
if(s[i]==')'||s[i]=='(') printf("()");
if(s[i]==']'||s[i]=='[') printf("[]");
}
else if(value[i][j]==-1){
printf("%c",s[i]);
print(i+1,j-1);
printf("%c",s[j]);
}
else{
print(i,value[i][j]);
print(value[i][j]+1,j);
}
return;
}
int main(){
while(getline(cin,s)){
//注意整行读入,有可能是空格
memset(d,0,sizeof(d));
len=(int)s.length();
for(int i=0; i<=len; i++) d[i][i]=1;
for(int tem=1; tem<len; tem++){//
for(int i=0; i<=len-tem; i++){
int j=tem+i;
d[i][j]=inf;
if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']')){
d[i][j]=d[i+1][j-1];
value[i][j]=-1;//匹配标志
}
for(int k=i; k<j; k++){
if(d[i][j]>d[i][k]+d[k+1][j]){//更新i-j的最小答案
d[i][j]=d[i][k]+d[k+1][j];
value[i][j]=k;//找到中间更新的点
}
}
}
}
print(0,len-1);
printf("\n");
}
}

本文介绍了一种通过动态规划解决括号匹配问题的算法,并提供了一个详细的实现案例。该算法能够找出给定字符串中需要添加最少数量的括号来达到正确匹配的方法。
785

被折叠的 条评论
为什么被折叠?



