• Codeforces Round #288 (Div. 2) E. Arthur and Brackets [dp 贪心]


    E. Arthur and Brackets
    time limit per test
    2 seconds
    memory limit per test
    128 megabytes
    input
    standard input
    output
    standard output

    Notice that the memory limit is non-standard.

    Recently Arthur and Sasha have studied correct bracket sequences. Arthur understood this topic perfectly and become so amazed about correct bracket sequences, so he even got himself a favorite correct bracket sequence of length 2n. Unlike Arthur, Sasha understood the topic very badly, and broke Arthur's favorite correct bracket sequence just to spite him.

    All Arthur remembers about his favorite sequence is for each opening parenthesis ('(') the approximate distance to the corresponding closing one (')'). For the i-th opening bracket he remembers the segment [li, ri], containing the distance to the corresponding closing bracket.

    Formally speaking, for the i-th opening bracket (in order from left to right) we know that the difference of its position and the position of the corresponding closing bracket belongs to the segment [li, ri].

    Help Arthur restore his favorite correct bracket sequence!

    Input

    The first line contains integer n (1 ≤ n ≤ 600), the number of opening brackets in Arthur's favorite correct bracket sequence.

    Next n lines contain numbers li and ri (1 ≤ li ≤ ri < 2n), representing the segment where lies the distance from the i-th opening bracket and the corresponding closing one.

    The descriptions of the segments are given in the order in which the opening brackets occur in Arthur's favorite sequence if we list them from left to right.

    Output

    If it is possible to restore the correct bracket sequence by the given data, print any possible choice.

    If Arthur got something wrong, and there are no sequences corresponding to the given information, print a single line "IMPOSSIBLE" (without the quotes).

    Sample test(s)
    Input
    4
    1 1
    1 1
    1 1
    1 1
    Output
    ()()()()
    Input
    3
    5 5
    3 3
    1 1
    Output
    ((()))
    Input
    3
    5 5
    3 3
    2 2
    Output
    IMPOSSIBLE
    Input
    3
    2 3
    1 4
    1 4
    Output
    (())()

    一把一把的泪啊,,,看错题搞了很久,,,然后dp时输出串也搞了很久,,,原来水水的贪心就能过,,,泪流满面,

    转一下贪心的思路: http://www.cnblogs.com/wuyuewoniu/p/4256013.html

    CF上给这道题打了dp和greedy两个标签,应该是两种做法都可以吧。下面说贪心的做法。

    题意:

    有一些配好对的括号,现在已知第i对括号,左右括号的距离在[Li, Ri]区间中。按照左括号出现的顺序编号。

    输出原括号序列。

    分析:

    因为括号是以栈的形式配对的,所以我们将这些区间也以栈的形式存储。

    假设第i对括号的左括号在位置p,则右括号只能在[p+Li, p+Ri]这个区间中。

    每放一个左括号,就将右括号对应的区间入栈。

    贪心的办法是,如果当前位置位于栈顶区间的范围内,则尽早入栈。

    贪心的理由是:因为早点使栈顶的括号配对,就有更大的机会使栈顶的第二队括号配上对。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<map>
      9 #include<set>
     10 #include<stack>
     11 #include<string>
     12 
     13 #define N 1205
     14 #define M 105
     15 #define mod 1000000007
     16 //#define p 10000007
     17 #define mod2 1000000000
     18 #define ll long long
     19 #define LL long long
     20 #define eps 1e-6
     21 #define inf 100000000
     22 #define maxi(a,b) (a)>(b)? (a) : (b)
     23 #define mini(a,b) (a)<(b)? (a) : (b)
     24 
     25 using namespace std;
     26 
     27 int n;
     28 char s[N];
     29 int l[N],r[N];
     30 int flag;
     31 int dp[605][605];
     32 
     33 void ini()
     34 {
     35     memset(dp,-1,sizeof(dp));
     36     int i;
     37     for(i=1;i<=n;i++){
     38         scanf("%d%d",&l[i],&r[i]);
     39     }
     40     flag=0;
     41     s[2*n]='';
     42 }
     43 
     44 int fun(int now,int tot,int st,int en)
     45 {
     46    // printf("now=%d tot=%d st=%d en=%d
    ",now,tot,st,en);
     47     int f1,f2;
     48     int i;
     49     int tot1,tot2;
     50     int ss,ee;
     51     if(dp[now][tot]!=-1){
     52         return dp[now][tot];
     53     }
     54     if(tot==1){
     55         if(l[now]==1){
     56             dp[now][tot]=1;
     57             return 1;
     58         }
     59         else{
     60             dp[now][tot]=0;
     61             return 0;
     62         }
     63     }
     64     ss=l[now];ee=r[now];
     65     if(ss%2==0) ss++;
     66     if(ee%2==0) ee--;
     67     for(i=ss;i<=min(ee,en-st);i+=2){
     68         tot1=(i+1)/2;
     69         tot2=tot-tot1;
     70         //printf(" i=%d tot1=%d tot2=%d
    ",i,tot1,tot2);
     71         if(tot2<0) break;
     72         if(tot1==1){
     73             f2=fun(now+1,tot2,st+2,en);
     74             if(f2>=1){
     75                 dp[now][tot]=1;
     76                 return 1;
     77             }
     78         }
     79         else if(tot1==tot){
     80             f1=fun(now+1,tot1-1,st+1,en-1);
     81             if(f1>=1){
     82                 dp[now][tot]=i;
     83                 return 1;
     84             }
     85         }
     86         else{
     87             f1=fun(now+1,tot1-1,st+1,st+i-1);
     88             f2=fun(now+tot1,tot2,st+i+1,en);
     89             if(f1>=1 && f2>=1){
     90                 dp[now][tot]=i;
     91                 return 1;
     92             }
     93         }
     94     }
     95     dp[now][tot]=0;
     96     return 0;
     97 }
     98 
     99 void solve()
    100 {
    101     flag=fun(1,n,1,2*n);
    102 }
    103 
    104 void print(int now,int tot)
    105 {
    106     int tot1,tot2;
    107     tot1=(dp[now][tot]+1)/2;
    108     tot2=tot-tot1;
    109     printf("(");
    110     if(tot1!=1)
    111         print(now+1,tot1-1);
    112     printf(")");
    113     if(tot1!=tot)
    114         print(now+tot1,tot2);
    115 
    116 }
    117 
    118 void out()
    119 {
    120    /* int i,j;
    121     printf("flag=%d
    ",flag);
    122     for(i=1;i<=n;i++){
    123         for(j=1;j<=n;j++){
    124             printf(" i=%d j=%d dp=%d
    ",i,j,dp[i][j]);
    125         }
    126     }*/
    127     if(flag==0){
    128         printf("IMPOSSIBLE
    ");
    129     }
    130     else{
    131         print(1,n);
    132         printf("
    ");
    133         //printf("%s
    ",s);
    134     }
    135 }
    136 
    137 int main()
    138 {
    139     //freopen("data.in","r",stdin);
    140     //freopen("data.out","w",stdout);
    141     //scanf("%d",&T);
    142     //for(int ccnt=1;ccnt<=T;ccnt++)
    143     //while(T--)
    144     while(scanf("%d",&n)!=EOF)
    145     {
    146         ini();
    147         solve();
    148         out();
    149     }
    150     return 0;
    151 }
  • 相关阅读:
    【转】Android应用开发allowBackup敏感信息泄露的一点反思
    【转】YUV420P的格式以及转换为RGB565的代码(Android摄像头的输出一般为YUV420P)
    Android存储访问及目录
    【转】Android仿QQ截图应用测试
    【转】[Android编程心得] Camera(OpenCV)自动对焦和触摸对焦的实现
    关于RGB转换YUV的探讨与实现
    Android Butterknife框架配置
    【转】android错误 aapt.exe已停止工作的解决方法
    如何屏蔽Button setClickable与setEnabled
    Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_3
  • 原文地址:https://www.cnblogs.com/njczy2010/p/4260073.html
Copyright © 2020-2023  润新知