codeforces #288 E(区间DP)
2015-01-29 09:38:25
思路:一道很好的DP题,感谢JayYe的耐心指导~
一开始考虑了差分约束...没想出来。。。
考虑区间DP,关键在于dp定义,我们定义dp[i][j]为第i个~第j个括号对形成一个封闭的匹配系统的可行性(也就是说i~j个括号对已经匹配,且没有除i~j以外的括号对在其中)
显然dp为1表示可行,0表示不可行。
进行记忆化搜索,以[1,n]为起点开始搜索。对于每一个阶段[a,b](当前处理a~b个括号对的匹配情况)有两种情况:
(1)第a对括号可以加在最外面,条件:len = (b-a)*2+1,l[a] <= len <= r[a],形成:( a+1,a+2,...,b),那么下一步考虑的是dp[a+1][b]
(2)第a对括号的右括号加在中间,形成:( a+1,...a+i) a+k+1,....,b,那么下一步考虑dp[a][i]和dp[i+1][b]
(我顺便用dp[i][j]记录下了处理区间[i,j]时第a对括号的放法,dp[i][j]==INF表示第a对括号放在最外面,dp[i][j]==0表示不可行,dp[i][j]==其他数表示加在中间)
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define MP(a,b) make_pair(a,b) 21 22 typedef long long ll; 23 typedef pair<int,int> pii; 24 const int INF = (1 << 30) - 1; 25 26 int n; 27 int l[605],r[605]; 28 int dp[605][605]; 29 char s[2300]; 30 31 bool Solve(int a,int b){ 32 if(a == b){ 33 if(l[a] <= 1) return true; 34 return false; 35 } 36 if(dp[a][b] != -1) 37 return dp[a][b]; 38 //( a+1,a+2...b-1,b ) ,在外围加第a对括号 39 int len = (b - a) * 2 + 1; 40 if(l[a] <= len && len <= r[a]){ 41 if(Solve(a + 1,b)){ 42 return dp[a][b] = INF; 43 } 44 } 45 //( a+1...a+k ) ...b-1,b,在中间加第a对括号 46 FOR(i,a,b - 1){ 47 if(Solve(a,i) && Solve(i + 1,b)){ 48 dp[a][b] = i; 49 return true; 50 } 51 } 52 dp[a][b] = 0; 53 return false; 54 } 55 56 void Print(int a,int b){ 57 if(a == b){ 58 printf("()"); 59 return; 60 } 61 if(dp[a][b] == INF){ 62 printf("("); 63 Print(a + 1,b); 64 printf(")"); 65 } 66 else{ 67 Print(a,dp[a][b]); 68 Print(dp[a][b] + 1,b); 69 } 70 } 71 72 int main(){ 73 MEM(dp,-1); 74 scanf("%d",&n); 75 REP(i,n) scanf("%d%d",&l[i],&r[i]); 76 if(Solve(1,n)){ 77 Print(1,n); 78 puts(""); 79 } 80 else printf("IMPOSSIBLE\n"); 81 return 0; 82 }