zoukankan      html  css  js  c++  java
  • cf935E

    题解:

    树形dp

    要记录一个最小的,一个最大的

    然后转移

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=10005;
    int p,m,g[N*2][105],f[N*2][105],T[N*2][2],size[N*2],num;
    char s[N*2];
    int build(int x,int y)
    {
        if (x==y)
         {
             num++;
             f[num][0]=g[num][0]=s[x]-'0';
             return num;
         }
        int l=0;
        for (int i=x;i<=y;i++)
         {
             if (s[i]=='(')l++;
             if (s[i]==')')l--;
             if (s[i]=='?'&&l==1)
              {
                 int l=build(x+1,i-1),r=build(i+1,y-1);
                 num++;
                 T[num][0]=l;T[num][1]=r;
                 size[num]=size[l]+size[r]+1;
                return num;
              }
         }
    }
    void dfs(int x)
    {
        if (!T[x][0]&&!T[x][1])return;
        dfs(T[x][0]);dfs(T[x][1]);
        int l=T[x][0],r=T[x][1];
        if (p<m)
         {
             for (int i=0;i<=p;i++)
              for (int j=0;j<=i;j++)
               if (j<=size[l]&&i-j<=size[r])
                g[x][i]=min(g[x][i],g[l][j]-f[r][i-j]);
             for (int i=0;i<=p;i++)
              for (int j=0;j<i;j++)
               if (j<=size[l]&&i-j-1<=size[r])
                g[x][i]=min(g[x][i],g[l][j]+g[r][i-j-1]);         
             for (int i=0;i<=p;i++)
              for (int j=0;j<=i;j++)
               if (j<=size[l]&&i-j<=size[r])
                f[x][i]=max(f[x][i],f[l][j]-g[r][i-j]);
             for (int i=0;i<=p;i++)
              for (int j=0;j<i;j++)
               if (j<=size[l]&&i-j-1<=size[r])
                f[x][i]=max(f[x][i],f[l][j]+f[r][i-j-1]);            
         }    
        else
         {
             for (int i=0;i<=m;i++)
              for (int j=0;j<=i;j++)
               if (j<=size[l]&&i-j<=size[r])
                g[x][i]=min(g[x][i],g[l][j]+g[r][i-j]);
             for (int i=0;i<=m;i++)
              for (int j=0;j<i;j++)
               if (j<=size[l]&&i-j-1<=size[r])
                g[x][i]=min(g[x][i],g[l][j]-f[r][i-j-1]);              
             for (int i=0;i<=m;i++)
              for (int j=0;j<=i;j++)
               if (j<=size[l]&&i-j<=size[r])
                f[x][i]=max(f[x][i],f[l][j]+f[r][i-j]);
             for (int i=0;i<=m;i++)
              for (int j=0;j<i;j++)
               if (j<=size[l]&&i-j-1<=size[r])
                f[x][i]=max(f[x][i],f[l][j]-g[r][i-j-1]);         
         } 
    }
    int main()
    {
        scanf("%s",&s);
        scanf("%d%d",&p,&m);
        memset(f,0x8f,sizeof f);
        memset(g,0x3f,sizeof g);
        int root=build(0,strlen(s)-1);
        dfs(root);
        printf("%d",f[root][min(p,m)]);
    }
  • 相关阅读:
    3月14日进度博客
    构建之法阅读笔记01
    课堂练习-全国疫情统计3
    课堂练习-全球疫情统计2
    课堂练习-全国疫情统计1
    跟我一起写 Makefile(五)
    跟我一起写 Makefile(四)
    跟我一起写 Makefile(三)
    跟我一起写 Makefile(二)
    跟我一起写 Makefile(一)
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8456322.html
Copyright © 2011-2022 走看看