TOJ 3295 括号序列(区间DP)

描述

给定一串字符串,只由 “[”、“]” 、“(”、“)”四个字符构成。现在让你尽量少的添加括号,得到一个规则的序列。

例如:“()”、“[]”、“(())”、“([])”、“()[]”、“()[()]”,都是规则的序列。这几个不是规则的,如:“(”、“[”、“]”、“)(”、“([()”。

输入

输入有多组测试数据。输入一串字符串序列,长度不大于255。

输出

输出最少添加的括号数目。

样例输入

()
(
([()
[[(([]

样例输出

0
1
2
4
题意

如上

题解

DP[i][j]代表区间[i,j]最大匹配数

枚举长度,如果左右端点匹配,dp[l][r]=dp[l+1][r-1]+2

然后再循环k=l---r-1    dp[l][r]=max(dp[l][r],dp[l][k]+dp[k+1][r])可能区间[l,r]最大的是由[l,k][k+1,r]两个区间最大值合并而来

最后输出总长度-最大匹配dp[0][suml],suml代表序列总长度

代码

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 int main()
 7 {
 8     char s[255];
 9     while(scanf("%s",s)!=EOF)
10     {
11         int dp[255][255]={0};
12         int suml=strlen(s);
13         for(int len=1;len<=suml;len++)
14             for(int l=0;l+len-1<suml;l++)
15             {
16                 int r=l+len-1;
17                 if(s[l]==‘(‘&&s[r]==‘)‘||s[l]==‘[‘&&s[r]==‘]‘)dp[l][r]=dp[l+1][r-1]+2;
18                 for(int k=l;k<r;k++)
19                     dp[l][r]=max(dp[l][r],dp[l][k]+dp[k+1][r]);
20             }
21         printf("%d\n",suml-dp[0][suml-1]);
22     }
23     return 0;
24 }

原文地址:https://www.cnblogs.com/taozi1115402474/p/9465284.html

时间: 2024-08-29 01:05:44

TOJ 3295 括号序列(区间DP)的相关文章

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

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

poj 2955 Brackets 括号匹配 区间dp

题意:最多有多少括号匹配 思路:区间dp,模板dp,区间合并. 对于a[j]来说: 刚開始的时候,转移方程为dp[i][j]=max(dp[i][j-1],dp[i][k-1]+dp[k][j-1]+2), a[k]与a[j] 匹配,结果一组数据出错 ([]]) 检查的时候发现dp[2][3]==2,对,dp[2][4]=4,错了,简单模拟了一下发现,dp[2][4]=dp[2][1]+dp[2][3]+2==4,错了 此时2与4已经匹配,2与3已经无法再匹配. 故转移方程改为dp[i][j]=

POJ - 2955 括号 (区间DP)

分析:区间DP的典型题,设dp[i][j]为i到j的最大匹配数 依次从小到大的区间进行更新 如果a[i]==a[j]那么产生新的匹配,dp[i][j]=max(dp[i][j],dp[i+1][j-1]+1) 再依次枚举断点从原先得到的匹配区间中转移,找最大值 dp[i][j]=max(dp[i][j],dp[i][i+k]+dp[i+k+1][j]); 代码如下: #include <cstdio> #include <iostream> #include <algorit

[poj2955]括号匹配(区间dp)

解题关键:了解转移方程即可. 转移方程:$dp[l][r] = dp[l + 1][r - 1] + 2$ 若该区间左右端点成功匹配.然后对区间内的子区间取max即可. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 using namesp

题目2 : 回文字符序列(区间DP)

时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个.内容相同位置不同的子序列算不同的子序列. 输入 第一行一个整数T,表示数据组数.之后是T组数据,每组数据为一行字符串. 输出 对于每组数据输出一行,格式为"

poj2955括号匹配 区间DP

类似于上一篇博文. #include<stdio.h> #include<string.h> const int maxn = 120; char s[maxn]; int dp[maxn][maxn]; int max(int x,int y) { return x>y?x:y; } int main() { int i,j,k; while(scanf("%s",s)) { if(strcmp(s,"end")==0) break;

『一本通』区间DP

石子合并 1 #include<bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 using namespace std; 4 int n,sm[505][505],bg[505][505],sum[505]; 5 inline int read() { 6 int x=0,f=1; char c=getchar(); 7 while(c<'0'||c>'9') {if(c=='-')f=-1; c=getchar();} 8 while(c>

[BZOJ 4350]括号序列再战猪猪侠 题解(区间DP)

[BZOJ 4350]括号序列再战猪猪侠 Description 括号序列与猪猪侠又大战了起来. 众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号 序列S合法,当且仅当: 1.( )是一个合法的括号序列. 2.若A是合法的括号序列,则(A)是合法的括号序列. 3.若A,B是合法的括号序列,则AB是合法的括号序列. 我们考虑match[i]表示从左往右数第i个左括号所对应的是第几个右 括号,现在他得到了一个长度为2n的括号序列,给了你m个信息,第i 个信息形如ai,bi,表示match

【基础练习】【区间DP】codevs3657 括号序列题解

题目描述 Description 我们用以下规则定义一个合法的括号序列: (1)空序列是合法的 (2)假如S是一个合法的序列,则 (S) 和[S]都是合法的 (3)假如A 和 B 都是合法的,那么AB和BA也是合法的 例如以下是合法的括号序列: (), [], (()), ([]), ()[], ()[()] 以下是不合法括号序列的: (, [, ], )(, ([]), ([() 现在给定一些由'(', ')', '[', ,']'构成的序列 ,请添加尽量少的括号,得到一个合法的括号序列. 输