POJ1141Brackets Sequence 解题报告

题目链接1

题目链接2

 

题目大意

给出一个括号序列,添加最少的括号使序列正确

 

解题思路

先将问题简单化,从求序列退化为求最小添加括号数的问题

用区间dp n³解决

f[l][r]表示使第l个到r个区间正确的最小添加数

1 :当l = r时, f[l][r] = f[l+1][r-1]

2 :  在l到j中,枚举中间点k,则f[l][r] = min (f[l][r], f[l][k] + f[k+1][r])

求出了最小添加括号数后,再来思考完整的问题

用递归解决输出方案

假设有一个 从 l 到 r 的区间

这个区间的最优解有两种情况:

1:有上述第1种情况求得

2:由上述第2种情况求得

对于 1, 先输出最左边的字符,再递归中间部分,再输出最右边的字符

对于2, 用w数组记录此时最优方案的分割点k,分别递归左半边和右半边

特别情况,当l = r 则需在这个地方添加一个括号与其配对 

注意

要对读入序列长度为0进行特判

不然会很惨

 

几个小时也调不出来qwq

完整代码加注释

突然发现我的代码好短

#include <bits/stdc++.h>
using namespace std;
char ch[105];
int f[105][105], w[105][105];
void out (int x) {
	if (ch[x] == '(' or ch[x] == ')')  cout << "()";
	else cout << "[]";
}//输出与单个括号配对的函数 
void print (int l, int r) {
	if (l > r) return;
	else if (l == r)  out (l);  //若l = r 则需在这个地方添加一个括号与其配对 
	else if (w[l][r] == 0)  cout << ch[l],  print (l + 1, r - 1),  cout << ch[r];  //上述情况1 
	else  print (l, w[l][r]),  print (w[l][r] + 1, r);   //上述情况2 
} //输出方案递归函数 
int main(){
    scanf ("%s", ch + 1);
    int len = strlen (ch + 1);
    if (!len) puts("");      //当长度为0的特判 
    memset (f, 0x3f, sizeof (f));
    for (int i = 1; i <= 101; i++)  f[i][i] = 1;  //长度为1的区间初值赋值为1 
    for (int l = 2; l <= len; l++)   //区间dp 
      for (int i = 1; i <= len - l + 1; i++) {
      	int j = i + l - 1;
      	if ((ch[i] == '[' and ch[j] == ']') or (ch[i] == '(' and ch[j] == ')'))  
		  if (l != 2) f[i][j] = f[i+1][j-1];  else f[i][j] = 0; //当这两个可以匹配的情况,注意:当长度为2时要特判 
      	for (int k = i; k < j; k++)  
		  if (f[i][j] > f[i][k] + f[k+1][j])  f[i][j] = f[i][k] + f[k+1][j], w[i][j] = k;  //枚举并记录下最优方案的分割点 
	  }
    print (1, len);
    return 0;
}

 

 

转载于:https://www.cnblogs.com/whx666/p/10624879.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值