UVa 1626 括号序列

https://vjudge.net/problem/UVA-1626

题意:

输入一个由 "(" 、 ")" 、 "[" 、 "]" 构成的序列,添加尽量少的括号,得到一个规则序列。

思路:

d[i][j]表示 i~j 需要添加的最少个数,具体看代码吧,我也只是看着刘汝佳的代码写的 。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<string>
 4 #include<cstring>
 5 using namespace std;
 6
 7 char s[105];
 8 int n;
 9 int d[105][105];
10
11
12 bool cmp(char a, char b)
13 {
14     return a == ‘(‘&& b == ‘)‘ || (a == ‘[‘&& b == ‘]‘);
15 }
16
17 void dp()
18 {
19
20     for (int i = 0; i < n; i++)
21     {
22         d[i + 1][i] = 0;    //初始化,对应于下面的d[i+1][j-1]
23                             //也就是如果为()或[],此时不需要添加括号
24         d[i][i] = 1;        //这个对应于单个‘(‘、‘)‘、‘[‘、‘]‘的情况
25     }
26
27     //从短区间开始枚举
28     for (int i = n - 2; i >= 0; i--)
29     {
30         for (int j = i + 1; j < n; j++)
31         {
32             d[i][j] = n;
33             //如果为()or[],则这最外面的不用管
34             if (cmp(s[i], s[j]))     d[i][j] = min(d[i][j], d[i + 1][j - 1]);
35             for (int k = i; k < j; k++)
36                 d[i][j] = min(d[i][j], d[i][k] + d[k + 1][j]);
37         }
38     }
39 }
40
41
42 void print(int i, int j)
43 {
44     if (i>j)    return;
45     if (i == j)
46     {
47         if (s[i] == ‘(‘ || s[i] == ‘)‘)      cout << "()";
48         else cout << "[]";
49         return;
50     }
51     int ans = d[i][j];
52     //如果和里面所要加的括号数一样,那么 i 和 j 是不需要加括号的
53     if (cmp(s[i], s[j]) && ans == d[i + 1][j - 1])
54     {
55         cout << s[i];
56         print(i + 1, j - 1);
57         cout << s[j];
58         return;
59     }
60
61     for (int k = i; k < j; k++)
62     {
63         if (ans == d[i][k] + d[k + 1][j])
64         {
65             print(i, k);
66             print(k + 1, j);
67             return;
68         }
69     }
70 }
71
72 int main()
73 {
74     //freopen("D:\\txt.txt", "r", stdin);
75     int T;
76     cin >> T;
77     getchar();
78     while (T--)
79     {
80         gets(s);
81         gets(s);
82         n = strlen(s);
83         dp();
84         print(0, n - 1);
85         cout << endl;
86         if (T) cout << endl;
87     }
88     return 0;
89 }
时间: 2024-12-14 09:35:54

UVa 1626 括号序列的相关文章

uva 1626 Brackets Sequence ?(动态规划)

状态表示方法:d[ i ][ j ]表示的是一条序列的开始和结束: 状态定义:d[ i ][ j ]表示字串s[ i~j ] 需要添加的数量. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n; char s[105]; int d[105][105]; bool match(char ch1,char ch2) { if((ch1=='['&&am

UVa 1626 Brackets sequence (动态规划)

题意:用最少的括号将给定的字符串匹配,输出最优解.可能有空行. 思路:dp. dp[i][j]表示将区间i,j之间的字符串匹配需要的最少括号数,那么 如果区间左边是(或[,表示可以和右边的字符串匹配,枚举中间断点k,如果str[i]==str[k]则dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j])表示不需要加入新的括号,也可以插入新的括号则dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]+1). 如果区间最左边字符

数据结构(括号序列,线段树):ZJOI 2007 捉迷藏

[题目描述] Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条走廊的分布使得任意两个屋子都互相可达. 游戏是这样进行的,孩子们负责躲藏,Jiajia负责找,而Wind负责操纵这N个屋子的灯.在起初的时候,所有的灯都没有被打开.每一次,孩子们只会躲 藏在没有开灯的房间中,但是为了增加刺激性,孩子们会要求打开某个房间的电灯或者关闭某个房间的电灯.为了评估某一次

【UOJ】【UR #2】猪猪侠再战括号序列(splay/贪心)

http://uoj.ac/problem/31 纪念伟大的没有调出来的splay... 竟然那个find那里写错了!!!!!!!!!!!!! 以后要记住:一定要好好想过! (正解的话我就不写了,太简单了.. #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #

喵哈哈村的括号序列

描述 喵哈哈村的括号序列和外界的括号序列实际上是一样的. 众所周知"()"这样的,就是一个标准的括号序列:"()()()()"这样也是括号序列:"((()))()"这样也是一个合法的括号序列.但是"((("这样,就不是一个合法的括号序列了. 现在沈宝宝非常好奇,给你一个字符串,请从中找出最长的合法括号序列出来. 不知道你能找到吗? 输入 第一行一个T,表示有T组数据.接下来T行,每一行都是一个字符串.保证字符串的长度小于100

UVa 673 括号平衡

思路:简单的匹配操作,利用栈. Code: #include<stdio.h> #include<string.h> char stack[135]; int main() { int n; scanf("%d",&n); getchar(); while(n-->0) { memset(stack,0,sizeof(stack)); char c; int top=0; int flag=1; while((c=getchar())!='\n')

3295: 括号序列 -(序列DP)

描述 给定一串字符串,只由 “[”.“]” .“(”.“)”四个字符构成.现在让你尽量少的添加括号,得到一个规则的序列. 例如:“()”.“[]”.“(())”.“([])”.“()[]”.“()[()]”,都是规则的序列.这几个不是规则的,如:“(”.“[”.“]”.“)(”.“([()”. 输入 输入有多组测试数据.输入一串字符串序列,长度不大于255. 输出 输出最少添加的括号数目. 样例输入 () ( ([() [[(([] 样例输出 0 1 2 4 题目来源 椒江校区第一届C语言编程大

BZOJ2209: [Jsoi2011]括号序列

传送门 splay练习. 考虑把括号序列转化成类似于区间最大/最小值的情况. 显然我们可以知道括号序列消完的情况肯定是$a$个)和$b$个(,那么把这些括号全部合法化的代价显然就是$\frac{a+1}{2}+\frac{b+1}{2}$. 接着我们可以把'('变为1,把')'变为-1,然后每次取左区间的连续最小值,右区间的连续最大值,就是$a$与$b$的大小. 因为存在区间翻转,所以需要把左/右区间的连续最大/小值都搞出来. splay即可. //BZOJ2209 //by Cydiater

九度oj 题目1337:寻找最长合法括号序列

题目描述: 给你一个长度为N的,由’(‘和’)’组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配:所有的右括号都有唯一的左括号匹配.例如:((()))()()便是一个长度为10的合法括号序列,而(()))( 则不是. 需要你求解的是,找出最长的合法括号子序列的长度,同时找出具有这样长度的序列个数. 输入: 测试数据包括多个,每个测试数据包含两行: 第一行为一个整数N,其中N不会超过10^6. 第二行为一个长度为N的字