zoukankan      html  css  js  c++  java
  • P2308 添加括号

    P2308 添加括号

    题解

    一看这题---我能AC

    看完这题---我要换题

    这题第二问其实就是一个链的石子合并,也就是不用处理环

    所以一三问怎么处理???

    数组 mid[ i ][ j ] 记录区间 [ l , r ] 的断点

    数组 le[ i ] 表示 a[i] 左边有几个左括号

    数组 ri[ i ] 表示 a[i] 右边有几个右括号

    递归处理一下括号数

    单数字两边肯定不能有括号

    我们在区间左右各标记上左右括号之后,继续向下递归,分别处理断开的两段区间

    递归处理括号数

     先输出数字周围的括号,再输出这个数字,注意每两个数字之间都是要有+连接的

    然后输出最小合并

    递归输出中间合并部分结果

    合并左半部分的值,合并右半部分的值,两个部分一起合并的值

    注意

    (=的时候也是要更新一下mid的,可能是为了不断动态更新我编不动了

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    
    using namespace std;
    
    typedef long long ll;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    int n,a[25],sum[25];
    int f[25][25],mid[25][25];
    int le[25],ri[25];
    
    void cnt(int l,int r)
    {
        if(l==r) return ;
        le[l]++;
        ri[r]++;
        cnt(l,mid[l][r]);
        cnt(mid[l][r]+1,r);
    }
    
    void print(int l,int r)
    {
        if(l==r) return;
        print(l,mid[l][r]);
        print(mid[l][r]+1,r);
        printf("%d ",sum[r]-sum[l-1]);
    }
    
    int main()
    {
        n=read();
        memset(f,0x7f,sizeof(f));
        for(int i=1;i<=n;i++) a[i]=read(),sum[i]=sum[i-1]+a[i],f[i][i]=0;
        
        for(int l=2;l<=n;l++)
          for(int i=1;i+l-1<=n;i++){
              int j=i+l-1;
              for(int k=i;k<j;k++){
                  if(f[i][k]+f[k+1][j]<=f[i][j]){
                      f[i][j]=f[i][k]+f[k+1][j];
                      mid[i][j]=k;
                  }
              }
            f[i][j]+=sum[j]-sum[i-1];
          }
        
        cnt(1,n);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=le[i];j++) printf("(");
            printf("%d",a[i]);
            for(int j=1;j<=ri[i];j++) printf(")");
            if(i!=n) printf("+");
        }
        printf("
    %d
    ",f[1][n]);
        print(1,n);
        
        return 0;
    }
  • 相关阅读:
    洛谷P3513 [POI2011]KON-Conspiracy
    柱状图 三分法+树状数组
    CF习题集三
    CF习题集二
    CF习题集一
    单调队列总结
    SP688 SAM
    lemon使用方法
    洛谷 P2403 [SDOI2010]所驼门王的宝藏 题解
    字符串学习笔记二
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11913011.html
Copyright © 2011-2022 走看看