分析:
1. s形如(s')后则[s']:只需要把s'变成规则的,则s就是规则了。
2. s形如(s':先把s'变成规则的,在把最后一个加")", 则s就是规则的了。
3. s形如[s'或者s')后者s']:同上。
4. 只要序列长度大于1, 都可以把S分成两部分Si。。。Sk, Sk+1。。。Sj, 分别变成规则序列,则连在一起
也是规则的序列。
对于程序一:我觉得是用到了第四条性质,由于计算f[i,j]需要知道f[i + 1, j], f[i, j - 1] 和d[i + 1, j - 1], 所以
由自底向上方法求出
程序一:
#include "iostream"
using namespace std;
const int size = 110;
char st[size]; //接收数组
int f[size][size]; //f[i][j]存储添加的最少值
int v[size][size]; //f[i][j]中的k值, 就是让两边都为规则的情况
//输出路径
void output(int s, int e)
{
if(s > e)
return;
else if(s == e)
{
if (st[s] =='('|| st[s] ==')')
cout<<"()";
else
cout<<"[]";
}
else if (v[s][e] ==-1)
{
cout<<st[s];
output(s + 1, e - 1);
cout<<st[e];
return;
}
else{
output(s, v[s][e]);
output(v[s][e] + 1, e);
}
}
int main(){
//freopen("in.txt", "r", stdin);
gets(st);
memset(f, -1, sizeof(f));
memset(v, -1, sizeof(v));
int i, j, k, len = strlen(st);
for(i = 0; i < len; i++){
f[i][i] = 1;
f[i + 1][i] = 0;
}
//自底向上进行dp
for(i = 1; i < len; i++){
for(j = 0; j < len - i; j++){
int s = j, e = j + i;
if((st[s] == '(' && st[e] == ')') || (st[s] == '[' && st[e] == ']'))
f[s][e] = f[s + 1][e - 1];
for(k = s; k < e; k++)
if(f[s][e] > f[s][k] + f[k][e] || f[s][e] == -1){
f[s][e] = f[s][k] + f[k + 1][e];
v[s][e] = k;
}
}
}
output(0, len - 1);
cout<<endl;
return 0;
}