poj1141(区间dp基础)

来源:互联网 发布:淘宝如何好评返现 编辑:程序博客网 时间:2024/06/01 08:40

Brackets Sequence
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 29414 Accepted: 8368 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

()[()]

题意:

给出只含有'('')''['']'这四种字符的字符串,要求让这个串匹配的最少需要添加的字符个数并且输出该字符串。

思路:

这题看起来比较水,可是自己想不是太好想,看了别人说要递归自己试了下还行,记忆化搜索写起来挺顺手,不过可惜这题刚开始把状态转移方程搞错了总是wa。

用dp[i][j]表示区间i到j之间的最少的需要匹配的字符对数,状态转移是:

如果x[i]和x[j]匹配,  dp[i][j]=min(dp[i+1][j-1]+1,dp[i][k]+dp[k+1][j]),

否则,  dp[i][j]=min(dp[i][k]+dp[k+1][j])

fen[i][j]表示区间i到j如果dp[i][j]=某一个dp[i][k]+dp[k+1][j],那么fen[i][j]=k表示区间i到j是从k这个地方分开的!而且这个fen[i][j]数组很必要,否则还得在输出的函数里要加上一大堆判断条件!

#include <iostream>#include <stdio.h>#include <stdlib.h>#include<string.h>#include<algorithm>#include<math.h>#include<queue>using namespace std;typedef long long ll;int dp[110][110];int fen[110][110];char x[110];int fdp(int a,int b){    if(dp[a][b]!=-1)return dp[a][b];    if(a==b)return dp[a][b]=1;    if(a>b)return dp[a][b]=0;    int min0=1e9;    if((x[a]=='('&&x[b]==')')||(x[a]=='['&&x[b]==']'))        min0=fdp(a+1,b-1)+1;    for(int k=a; k<b; k++)        if(min0>fdp(a,k)+fdp(k+1,b))            min0=fdp(a,k)+fdp(k+1,b),fen[a][b]=k;    return dp[a][b]=min0;}void prin(int a,int b){    if(a==b)    {        if(x[a]=='('||x[a]==')')            printf("()");        else printf("[]");        return;    }    if(a>b)        return;    if(fen[a][b]==-1)    {        if(x[a]=='(')        {            printf("(");            prin(a+1,b-1);            printf(")");        }        else        {            printf("[");            prin(a+1,b-1);            printf("]");        }        return ;    }    prin(a,fen[a][b]);    prin(fen[a][b]+1,b);}int main(){    scanf("%s",x);    memset(dp,-1,sizeof(dp));    memset(fen,-1,sizeof(fen));    int l=strlen(x);    fdp(0,l-1);    prin(0,l-1);    puts("");    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 婴儿乘飞机没带证件怎么办 吃了轮状发烧怎么办 儿童票比打折票贵怎么办 订机票订错了怎么办 如果飞机不支持婴儿票怎么办 报志愿登不上去怎么办 微单自拍是反的怎么办 蜡笔弄到桌子上怎么办 油画颜料干透了怎么办 数字油画颜料干了怎么办 数字油画的颜料干了怎么办 丙烯颜料画错了怎么办 油画的油干了怎么办 数字油画没画完颜料干了怎么办? 涂完口红很干怎么办 吃鸡匹配不到人怎么办 电脑吃鸡更新慢怎么办 苹果手机吃鸡更新不了怎么办 吃鸡更新硬盘不够怎么办 吃鸡链接不到更新服务器怎么办 6s吃鸡更新不了怎么办 凌美钢笔刮纸怎么办 毕加索钢笔不出水怎么办妙招 打印机总显示墨水已用完怎么办 樱花勾线笔干了怎么办 枣核卡在喉咙里怎么办 马桶被玉米棒堵了怎么办 雪糕棒掉马桶里了怎么办 食用色素吃多了怎么办 蜡笔弄到指甲里怎么办 小孩把彩笔吃了怎么办 宝宝吃了水彩笔怎么办 宝宝不小心吃了蜡笔怎么办 小孩把蜡笔吃了怎么办 宝宝吃了记号笔怎么办 二年级的孩子不太爱看书怎么办 数字油画涂错了怎么办 白墙上被蜡笔画起来怎么办 衣服上的油画棒怎么办 蜡笔要是涂错了怎么办 蜡笔颜色涂错了怎么办