coincidente mínimo poj1141 Soportes dp intervalo

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");
}

 

Publicado 31 artículos originales · ganado elogios 5 · Vistas 1366

Supongo que te gusta

Origin blog.csdn.net/qq_43685900/article/details/102881382
Recomendado
Clasificación