Brackets Sequence POJ - 1141 (区间dp)

Brackets Sequence

POJ - 1141

题意:给一个括号序列,问最少添加多少个括号似的原序列匹配,并输出新序列。

用dp[i][j]表示i到j最少添加几个括号,flag[i][j]表示i和j之间需要添加括号的位置。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<string>
 4 #include<iostream>
 5 #include <cstdlib>
 6 #include<cstring>
 7 using namespace std;
 8 const int maxn=110;
 9 const int inf=0x3f3f3f3f;
10 int dp[maxn][maxn],flag[maxn][maxn];
11 char s[maxn];
12
13 void print(int l,int r){
14     if(l>r) return ;
15     if(l==r){
16         if(s[l]==‘(‘||s[l]==‘)‘) printf("()");
17         else printf("[]");
18         return ;
19     }
20     if(flag[l][r]==-1){
21         putchar(s[l]);
22         print(l+1,r-1);
23         putchar(s[r]);
24     }else {
25         print(l,flag[l][r]);
26         print(flag[l][r]+1,r);
27     }
28 }
29 int main(){
30     while(gets(s)){
31         memset(dp,0,sizeof(dp));
32         int len=strlen(s);
33         for(int i=0;i<len;i++) dp[i][i]=1;
34         for(int i=len-2;i>=0;i--)
35             for(int j=i+1;j<len;j++){
36             dp[i][j]=inf;
37             if(s[i]==‘(‘&&s[j]==‘)‘||s[i]==‘[‘&&s[j]==‘]‘)
38             if(dp[i][j]>dp[i+1][j-1]){
39                 dp[i][j]=dp[i+1][j-1];
40                 flag[i][j]=-1;
41             }
42             for(int k=i;k<j;k++)
43                 if(dp[i][j]>dp[i][k]+dp[k+1][j]){
44                     dp[i][j]=dp[i][k]+dp[k+1][j];
45                     flag[i][j]=k;
46                 }
47         }
48         print(0,len-1);
49         puts("");
50     }
51 }

v1

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<string>
 4 #include<iostream>
 5 #include <cstdlib>
 6 #include<cstring>
 7 using namespace std;
 8 const int maxn=110;
 9 const int inf=0x3f3f3f3f;
10 int dp[maxn][maxn],flag[maxn][maxn];
11 char s[maxn];
12
13 void print(int l,int r){
14     if(l>r) return ;
15     if(l==r){
16         if(s[l]==‘(‘||s[l]==‘)‘) printf("()");
17         else printf("[]");
18         return ;
19     }
20     if(flag[l][r]==-1){
21         putchar(s[l]);
22         print(l+1,r-1);
23         putchar(s[r]);
24     }else {
25         print(l,flag[l][r]);
26         print(flag[l][r]+1,r);
27     }
28 }
29 int main(){
30     while(gets(s)){
31         memset(dp,0,sizeof(dp));
32         int len=strlen(s);
33         for(int i=0;i<len;i++) dp[i][i]=1;
34         for(int k=1;k<len;k++){
35             for(int i=0;i+k<len;i++){
36                 int j=i+k;
37                 dp[i][j]=inf;
38                 if(s[i]==‘(‘&&s[j]==‘)‘||s[i]==‘[‘&&s[j]==‘]‘)
39                 if(dp[i][j]>dp[i+1][j-1]){
40                     dp[i][j]=dp[i+1][j-1];
41                     flag[i][j]=-1;
42                 }
43                 for(int m=i;m<j;m++){
44                     if(dp[i][j]>dp[i][m]+dp[m+1][j]){
45                         dp[i][j]=dp[i][m]+dp[m+1][j];
46                         flag[i][j]=m;
47                     }
48                 }
49             }
50         }
51         print(0,len-1);
52         puts("");
53     }
54 }

v2

时间: 2024-11-11 01:27:03

Brackets Sequence POJ - 1141 (区间dp)的相关文章

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

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

UVA-1626 Brackets sequence (简单区间DP)

题目大意:给一个有小括号和中括号组成的序列,满足题中的三个条件时,是合法的.不满足时是不合法的,问将一个不合法的序列最少添加几个括号可以使之变成合法的.输出最短合法序列. 题目分析:这是<入门经典>上的一道例题.如果仅让求最短序列是极简单的,定义dp(i,j)表示将区间 i~j 变为合法添加的最小字符数. 则 dp(i,j)=dp(i+1,j-1)   (i与j能匹配时), dp(i,j)=min(dp(i,k)+dp(k+1,j)). 但是,输出的时候就比较慢了.从左往右通过比较选择最优方案

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