poj-2955 (区间dp)

Brackets

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5150   Accepted: 2761

Description

We give the following inductive definition of a “regular brackets” sequence:

  • the empty sequence is a regular brackets sequence,
  • if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
  • if a and b are regular brackets sequences, then ab is a regular brackets sequence.
  • no other sequence is a regular brackets sequence

For instance, all of the following character sequences are regular brackets sequences:

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

while the following character sequences are not:

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

Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1i2, …, im where 1 ≤ i1 < i2 < … < im ≤ nai1ai2 … aim is a regular brackets sequence.

Given the initial sequence ([([]])], the longest regular brackets subsequence is [([])].

Input

The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters ()[, and ]; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.

Output

For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.

Sample Input

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

Sample Output

6
6
4
0
6AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char str[150];
int dp[120][120];
int main()
{
    while(1)
    {
        scanf("%s",str);
        if(str[0]==‘e‘)break;
    int len=strlen(str);
    memset(dp,0,sizeof(dp));
    for(int j=0;j<len;j++)
    {
        for(int i=j-1;i>=0;i--)
        {
            dp[i][j]=dp[i+1][j];
            for(int k=i+1;k<=j;k++)
            {
                if((str[i]==‘(‘&&str[k]==‘)‘)||(str[i]==‘[‘&&str[k]==‘]‘))
                   {
                       dp[i][j]=max(dp[i][j],dp[i+1][k-1]+dp[k+1][j]+2);
                   }
            }
        }
    }
    cout<<dp[0][len-1]<<"\n";
    }
    return 0;
}
时间: 2024-10-25 02:17:36

poj-2955 (区间dp)的相关文章

poj 2955 区间dp(括号匹配)

#include<stdio.h> #include<string.h> #include<iostream> using namespace std; int max(int a,int b) { return a>b?a:b; } int main() { char str[110]; int dp[110][110]; int i,j; while(~scanf("%s",str)) { int len=strlen(str); if(s

POJ 2955 区间DP Brackets

求一个括号的最大匹配数,这个题可以和UVa 1626比较着看. 注意题目背景一样,但是所求不一样. 回到这道题上来,设d(i, j)表示子序列Si ~ Sj的字符串中最大匹配数,如果Si 与 Sj能配对,d(i, j) = d(i+1, j-1) 然后要枚举中间点k,d(i, j) = max{ d(i, k) + d(k+1, j) } 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #

poj 2955 Brackets dp简单题

//poj 2955 //sep9 #include <iostream> using namespace std; char s[128]; int dp[128][128]; int n; int rec(int l,int r) { if(dp[l][r]!=-1) return dp[l][r]; if(l==r) return dp[l][r]=0; if(l+1==r){ if(s[l]=='('&&s[r]==')') return dp[l][r]=2; if(

poj 3280(区间DP)

Cheapest Palindrome Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7869   Accepted: 3816 Description Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow a

poj 1141 区间dp

题目链接:http://poj.org/problem?id=1141 题解:略 代码: #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define ll long long const int maxn=1e2+5; const int INF=0x3f3f3f3f; int dp[105][105]; int

poj 1651 区间dp

题目链接:http://poj.org/problem?id=1651 Description The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the prod

POJ 1651 区间DP Multiplication Puzzle

此题可以转化为最优矩阵链乘的形式,d(i, j)表示区间[i, j]所能得到的最小权值. 枚举最后一个拿走的数a[k],状态转移方程为d(i, j) = min{ d(i, k) + d(k, j) + a[i] * a[k] * a[j] } 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std;

poj 1651(区间dp)

乱改出真知,做不动了,水平有限,大概了解一下,去做树形dp了,以后回来再学 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn=100+10; int a[maxn]; int dp[maxn][maxn]; int n; const int inf=0x3f3f3f3f; int m

poj 3186区间dp

给你一个数列   然后从里面取数  只能从队头或队尾取出   取出的值乘以取出的顺序i(及第几个取出的)  求累加和的最大值: dp[i][j]表示去了i次   从左边去了j个的最大值:  然后地推下去: dp[i][j]=max(dp[i-1][j]*num[j]*i,num[i-1][j]+num[n-i+j+1]*i)注意j为0的情况:再说这道题坑吧     num数组开为局部变量wa   开为int64  还是wa  真是无语了 #include<stdio.h> #include&l

poj 1141 区间dp+递归打印路径

Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30383   Accepted: 8712   Special Judge Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a re