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 regular sequence, then (S) and [S] are both regular sequences. 
3. If A and B are regular sequences, then AB is a regular sequence.

For example, all of the following sequences of characters are regular brackets sequences:

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

And all of the following character sequences are not:

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

Some sequence of characters ‘(‘, ‘)‘, ‘[‘, and ‘]‘ is given. You are to find the shortest possible regular brackets sequence, that contains the given character sequence as a subsequence. Here, a string a1 a2 ... an is called a subsequence of the string b1 b2 ... bm, if there exist such indices 1 = i1 < i2 < ... < in = m, that aj = bij for all 1 = j = n.

Input

The input file contains at most 100 brackets (characters ‘(‘, ‘)‘, ‘[‘ and ‘]‘) that are situated on a single line without any other characters among them.

Output

Write to the output file a single line that contains some regular brackets sequence that has the minimal possible length and contains the given sequence as a subsequence.

Sample Input

([(]

Sample Output

()[()]

Source

#include<iostream>
#include<stdio.h>
#include<string>
#include<cstring>
//#include<bits/stdc++.h>
using namespace std;
const int maxn = 110;
const int inf = 0x3f3f3f3f;
char s[maxn];
int dp[maxn][maxn],choose[maxn][maxn];
void printstr(int i,int j)
{
    if(i>j)
        return ;
    if(i==j)
    {
        if(s[i]==‘(‘||s[i]==‘)‘) printf("()");
        else printf("[]");
        return;
    }
    if(choose[i][j]==-1)
    {
        printf("%c",s[i]);
        printstr(i+1,j-1);
        printf("%c",s[j]);
    }
    else
    {
        printstr(i,choose[i][j]);
        printstr(choose[i][j]+1,j);
    }
}
int main()
{
    int t;
    //scanf("%d",&t);
    cin>>s;

        int len =strlen(s);
        for(int i=0; i<len; i++)
            dp[i][i]=1,dp[i+1][i]=0;
        for(int p=1; p<len; p++)
        {
            for(int i=0,j=i+p; j<len; i++,j++)
            {
                dp[i][j]=inf;
                choose[i][j]=-1;
                if(s[i]==‘(‘&&s[j]==‘)‘||s[i]==‘[‘&&s[j]==‘]‘)
                    dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
                for(int k=i; k<j; k++)
                {
                    if(dp[i][j]>dp[i][k]+dp[k+1][j])
                    {
                        choose[i][j]=k;
                        dp[i][j]=dp[i][k]+dp[k+1][j];
                    }
                }
            }
        }
        printstr(0,len-1);
        printf("\n");
    return 0;
}

时间: 2024-08-02 07:37:58

poj 1141 区间dp+递归打印路径的相关文章

DP(递归打印路径) UVA 662 Fast Food

题目传送门 题意:n个饭店在一条直线上,给了它们的坐标,现在要建造m个停车场,饭店没有停车场的要到最近的停车场,问所有饭店到停车场的最短距离 分析:易得区间(i, j)的最短距离和一定是建在(i + j) / 2的饭店,预处理出(i, j)的距离和sum[i][j],mark[i][j] 表示区间的最优停车场的位置,mid[i][j]表示(i + j) / 2.状态转移方程:dp[i][j] = max (dp[k-1][j-1] + sum[k][i]): 收获:学习递归打印路径 代码: /*

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

FatMouse&#39;s Speed ~(基础DP)打印路径的上升子序列

FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speed

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

uva 10453 Make Palindrome (区间DP + 递归输出)

uva 10453 Make Palindrome 题目大意:给出一段字符串,要求求出最少加入几个字符(任意位置),可以让该字符串变成会问字符串,并输出修改以后的回文字符串. 解题思路:dp[i][j]代表了将该字符串从第i位到第j位变成回文字符串最少要添加的字符.当S[i]==S[j],dp[i][j]=dp[i+1][j?1]当S[i]!=S[j],dp[i][j]=min(dp[i+1][j],dp[i][j?1])+1,在DP的过程中记录对该区间的操作类型,最后递归输出. #includ

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