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)]);
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8456322.html