El significado de los problemas
Le das una cadena que desea hacer coincidir la cadena más corta de salida mínima
entrada:
salida:
pensamiento
dp [i] [j] - un número mínimo de partidos entre i ~ j.
Inicialización memset (0) dp [i] [i] = 1;
. Longitud enumeración primer lugar, si (is_same (extremos)) dp [i] [j] = dp [i + 1] [j - 1], pos [i] [j] = -1; // etiqueta
Tome min (dp [i] [j], dp [i] [k] + dp [k + 1] [j]); pos [i] [j] = k; // división registro
Print () de salida de forma recursiva
Accode
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
const int inf = 0x3f3f3f3f;
string s;
int dp[105][105],pos[105][105];
int n;
void Print(int i,int j){
if(i > j) return ;
if(i == j){
if(s[i] == '(' || s[i] == ')') printf("()");
else printf("[]");
return ;
}
if(pos[i][j] == -1){
printf("%c",s[i]);
Print(i + 1,j - 1);
printf("%c",s[j]);
return ;
}
else{
Print(i,pos[i][j]);
Print(pos[i][j] + 1,j);
return ;
}
}
bool is_same(char A,char B){
if(A == '(' && B == ')') return 1;
else if(A == '[' && B == ']') return 1;
return 0;
}
int main()
{
getline(cin,s);//可能有空串
n = s.size();
for(int i = 0;i < n; i++){
for(int j = 0;j < n; j++){
dp[i][j] = 0;
}
}
for(int i = 0;i < n; i++) dp[i][i] = 1;//添加匹配一对
for(int L = 1;L < n; L++){//length
for(int i = 0;i + L < n; i++){
int j = i + L;
dp[i][j] = inf;
if(is_same(s[i],s[j])){
dp[i][j] = dp[i + 1][j - 1];
pos[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];
pos[i][j] = k;
}
}
}
}
Print(0,n - 1);
printf("\n");
}