poj 1141 Brackets Sequence(区间dp)
2015-06-17 21:54
477 查看
Language: Default Brackets Sequence
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 ()[()] |
借鉴别人的思路:
思路:dp[i][j]表示从区间i到区间j使其所以括号匹配需要补上的最少括号数,那么当出现一个括号时,首先考虑它不与后面匹配的情况,那么需要加一个相对应的括号,让之匹配dp[i][j]=dp[i+1][j]+1;
然后再考虑,若是后面有括号可以让它匹配的情况,那么假设i<k<=j,当s[i]=='('&&s[k]==')'的时候,考虑动态转移,dp[i][j]=dp[i+1][k-1]+dp[k][j]-1
为什么这个动态方程减1呢,因为我将与之匹配的那个括号重新计算了一次,当s[k]==')'的时候,在计算dp[k][k]的时候,我的状态转移已经把这个括号自动匹配了一次,所以要减去这次匹配的........
然后就是记录路径了,开一个二维数组a[i][j],当a[i][j]==-1的时候,表示dp[i][j]这个状态是从dp[i+1][j]推导过来的,当a[i][j]>0的时候,表示dp[i][j]是从dp[i+1][a[i][j]-1]以及dp[k][j]这两个状态推导过来的,那么注意到当a[i][j]!=-1的时候,就正好表示s[i]与s[a[i][j]]匹配,说明在第i个括号这个地方只需要输出它自己本身,其他的,若是a[i][j]==-1的,都需要输出它自身以及与它自身匹配的括号.........
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <string.h> #include <string> #include <vector> #include <queue> #define MEM(a,x) memset(a,x,sizeof a) #define eps 1e-8 #define MOD 10009 #define MAXN 10010 #define MAXM 100010 #define INF 99999999 #define ll __int64 #define bug cout<<"here"<<endl #define fread freopen("ceshi.txt","r",stdin) #define fwrite freopen("out.txt","w",stdout) using namespace std; int Read() { char c = getchar(); while (c < '0' || c > '9') c = getchar(); int x = 0; while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x; } void Print(int a) { if(a>9) Print(a/10); putchar(a%10+'0'); } char ch[110]; int dp[110][110]; int pos[110][110],vis[110]; void visit(int s,int t) { if(s>=t) return; if(pos[s][t]==-1) visit(s+1,t); if(pos[s][t]>0) { vis[s]=1; vis[pos[s][t]]=1; visit(s,pos[s][t]-1); visit(pos[s][t],t); } } int main() { // fread; while(gets(ch)) { int len=strlen(ch); len--; // cout<<"len "<<len<<endl; MEM(vis,0); MEM(vis,0); MEM(pos,-1); for(int i=0;i<=len;i++) dp[i][i]=1; for(int i=len-1;i>=0;i--) { for(int j=i+1;j<=len;j++) { dp[i][j]=dp[i+1][j]+1; pos[i][j]=-1; for(int k=i+1;k<=j;k++) if(ch[i]=='('&&ch[k]==')'||ch[i]=='['&&ch[k]==']') { if(dp[i][j]>dp[i+1][k-1]+dp[k][j]-1) { dp[i][j]=dp[i+1][k-1]+dp[k][j]-1; pos[i][j]=k; } } } } visit(0,len); for(int i=0;i<=len;i++) { if(vis[i]) printf("%c",ch[i]); else { if(ch[i]=='('||ch[i]==')') printf("()"); else printf("[]"); } } puts(""); } return 0; }
相关文章推荐
- 黑马程序员------判断语句、循环语句及break、continue
- 【嘟嘟工作室】 UEFI GUI 最新界面 duduworks@163.com
- android-UI组件
- Algs4-2.2.2 归并算法为EASYQUESTION排序的轨迹
- UI数据库
- 多线程03-NSOperationQueue(掌握)
- hdoj 1242 Rescue
- UI之UINavigationBar的用法
- 用scrapy框架时,出现问题:ValueError: invalid literal for int() with base 10: 'dev0'
- 初步认识BLE到熟悉,浅谈!
- Children’s Queue(hdu1297+递推)
- uiscrollView更新
- UITextField
- Children’s Queue(递推)
- iOS开发-UITapGestureRecognizer手势
- 再学习 break&continue
- Bluemix云平台实践: 命令行的艺术CF CLI
- pyside 内嵌 mayaui
- Java - String vs StringBuffer vs StringBuilder in Java
- Android中UI线程与后台线程交互设计的5种方法