UVa 1626 - Brackets sequence (区间dp)

题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=4501&mosmsg=Submission+received+with+ID+26616028

区间dp

如果 s 形如 '(s)' 或 '[s]',则可转移到 s
如果 s 至少有两个字符,则可分解成两部分 AB

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 105;

int T, n;
int dp[maxn][maxn];
char s[maxn];

bool match(int i, int j){ return (s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']'); }

void print(int i, int j){
	if(i == j){
		if(s[i] == '(' || s[i] == ')') printf("()");
		else printf("[]");
		return;
	}
	
	if(match(i, j) && (dp[i][j] == dp[i+1][j-1] + 2)) {
		if(i+1 == j){
			if(s[i] == '(') printf("()");
			else printf("[]");
			return;
		}
		if(s[i] == '('){
			printf("(");
			print(i + 1, j - 1);
			printf(")");
		} else{
			printf("[");
			print(i + 1, j - 1);
			printf("]");
		}
	} else{
		for(int k = i ; k < j ; ++k){
			if(dp[i][k] + dp[k+1][j] == dp[i][j]){
				print(i, k); print(k+1, j);
				break;
			}
		}
	}
}

void readline(char* S) {
    fgets(S, maxn, stdin);
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	readline(s);
  	sscanf(s, "%d", &T);
  	readline(s);
	int flag = 0;
	while(T--){
		readline(s);
		n = strlen(s) - 1;
		
		memset(dp, 0x3f, sizeof(dp));
		
		for(int i = 0 ; i < n ; ++i){
			dp[i][i] = 2;
			dp[i+1][i] = 0;
		}
		
		for(int l = 2 ; l <= n ; ++l){
			for(int i = 0 ; i + l - 1 < n ; ++i){
				int j = i + l - 1;
				if(match(i, j)) dp[i][j] = min(dp[i][j], dp[i+1][j-1] + 2); // '[][]'
				for(int k = i ; k < j ; ++k){
					dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]);
				}
			}
		}
		
		print(0, n-1);
		printf("\n");
		if(T) printf("\n");
    	readline(s);
	}
	return 0;
}
posted @ 2021-07-26 16:20  Tartarus_li  阅读(28)  评论(0编辑  收藏  举报