[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 namespace std;
 8 typedef long long ll;
 9 int dp[202][202];
10 int main(){
11     string s;
12     ios::sync_with_stdio(0);
13     while(cin>>s){
14         memset(dp,0,sizeof dp);
15         if(s=="end") break;
16         for(int len=1;len<=s.size();len++){
17             for(int l=0,r;(r=l+len-1)<s.size();l++){
18                 if((s[l]==‘(‘&&s[r]==‘)‘)||(s[l]==‘[‘&&s[r]==‘]‘)) dp[l][r]=dp[l+1][r-1]+2;
19                 for(int i=0;i<r;i++) dp[l][r]=max(dp[l][i]+dp[i+1][r],dp[l][r]);
20             }
21         }
22         cout<<dp[0][s.size()-1]<<"\n";
23     }
24     return 0;
25 }
时间: 2024-10-12 13:47:41

[poj2955]括号匹配(区间dp)的相关文章

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;

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]=

TOJ 3295 括号序列(区间DP)

描述 给定一串字符串,只由 "["."]" ."(".")"四个字符构成.现在让你尽量少的添加括号,得到一个规则的序列. 例如:"()"."[]"."(())"."([])"."()[]"."()[()]",都是规则的序列.这几个不是规则的,如:"("."[".&quo

POJ2955 Brackets 题解 区间DP

题目链接:http://poj.org/problem?id=2955[题目描述]<规则的括号序列>我们定义一个字符串序列为“规则的括号序列”当且仅当它满足如下条件:1.空字符串是规则的括号序列:2.如果字符串 s 是一个规则的括号序列,那么 (s) 和 [s] 也是规则的括号序列:3.如果字符串 a 和 b 都是规则的括号序列,那么 ab 也是规则的括号序列:4.除此之外的字符串都不能称为规则的括号序列.举个例子,下面的这些字符串都是规则的括号序列: (), [], (()), ()[],

POJ2955 Brackets(区间DP)

给一个括号序列,求有几个括号是匹配的. dp[i][j]表示序列[i,j]的匹配数 dp[i][j]=dp[i+1][j-1]+2(括号i和括号j匹配) dp[i][j]=max(dp[i][k]+dp[k+1][j])(i<=k<j) 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 char str[111]; 6 int d[111

poj2955 Brackets 简单区间dp

// poj2955 简单区间dp // d[i][j]表示i到j区间所能形成的最大匹配序列 // dp[i][j] = max(dp[i][k]+dp[k+1][j]){i<k<j} // dp[i][j] = max(dp[i+1][j-1]+2) if (s[i] match s[j]) // // 记忆化搜索的时候,将dp[i][i] = 0 ,其他赋值成-1; // // 做题的时候刚开始将dp[i][j]弄成0了,结果一直tle // 最后发现有好多的状态重复计算了,所以会tle

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——括号匹配

题目:http://poj.org/problem?id=2955 区间DP. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; char c[105]; int f[105][105]; bool p(char x,char y) { if((x=='('&&y==')')||(x=='['&&y==']'))return t

POJ2955 Brakets(区间dp)

我们知道一个的是0,因此先初始化两个长度的时候 之后运用区间dp的思想,如果s[l]和s[r]满足是一对,那么先由内部更新 之后我们枚举断点,计算相加的情况 #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<string> #include<cstring> #include&l