分析:
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; }