zoukankan      html  css  js  c++  java
  • 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;
    }
    

     

  • 相关阅读:
    如何搜索 git 提交记录
    使用Mongo进行分页
    mongodb 数据自动备份
    linux 添加环境变量
    centos7安装bbr
    centos7安装node
    [shell]输出内容到剪切板
    centos 7 已经开启 22 端口但无法连接
    一些有趣的 js 包
    机房选择
  • 原文地址:https://www.cnblogs.com/whx666/p/10624879.html
Copyright © 2011-2022 走看看