cf935e(树形dp)

树型dp也是练得少啊 。。弄了半天才好。。

这个就是把数字看成叶子,把?看出非叶子结点就行了。。。

然后其实+-号的个数只看其中一个,另外一个就已经知道了,不用理会。。

设d[i][j]、f[i][j]为使用了j个+号,i结点为根子树中的表达式的最大值和最小值

然后分别转移就可以。。注意无论最大还是最小,+和-都要尝试。。举一些全为负数的例子应该就能明白。。

最后坑爹的地方就是。。把min(m,p)<100看成了max(m,p)<100。。。所以会出现+号贼多的情况。。要先预判一下看+还是看-。。。




/**
 *        ┏┓    ┏┓ 
 *        ┏┛┗━━━━━━━┛┗━━━┓
 *        ┃       ┃   
 *        ┃   ━    ┃ 
 *        ┃ >   < ┃ 
 *        ┃       ┃ 
 *        ┃... ⌒ ...  ┃ 
 *        ┃       ┃ 
 *        ┗━┓   ┏━┛ 
 *          ┃   ┃ Code is far away from bug with the animal protecting           
 *          ┃   ┃   神兽保佑,代码无bug 
 *          ┃   ┃            
 *          ┃   ┃         
 *          ┃   ┃ 
 *          ┃   ┃            
 *          ┃   ┗━━━┓ 
 *          ┃       ┣┓ 
 *          ┃       ┏┛ 
 *          ┗┓┓┏━┳┓┏┛ 
 *           ┃┫┫ ┃┫┫ 
 *           ┗┻┛ ┗┻┛ 
 */  
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 20005
#define nm 105
#define pi 3.1415926535897931
using namespace std;
const ll inf=1000000007;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}


int root,d[NM][nm],f[NM][nm],l[NM],r[NM],m,tot,tmp,n,_f=1;
char s[NM];
void dfs(int &x,int &i){
	i=++tot;
	inc(j,0,n)d[i][j]=-inf,f[i][j]=inf;
	if(isdigit(s[x])){d[i][0]=f[i][0]=s[x]-'0';return;}
	dfs(++x,l[i]);
	dfs(x+=2,r[i]);
	x++;
	inc(j,0,n)inc(k,0,j-(_f^1))
		f[i][j]=min(f[i][j],f[l[i]][k]-d[r[i]][j-k-(_f^1)]),
		d[i][j]=max(d[i][j],d[l[i]][k]-f[r[i]][j-k-(_f^1)]);
	inc(j,0,n)inc(k,0,j-(_f^0))
		d[i][j]=max(d[i][j],d[l[i]][k]+d[r[i]][j-k-(_f^0)]),
		f[i][j]=min(f[i][j],f[l[i]][k]+f[r[i]][j-k-(_f^0)]);
}

int main(){
	//freopen("data.in","r",stdin);
	scanf("%s",s+1);
	m=strlen(s);
	n=read();tmp=read();
	if(tmp<n){swap(tmp,n);_f=0;}
	tmp=1;
	dfs(tmp,root);
	printf("%d\n",d[root][n]);
	return 0;
}







E. Fafa and Ancient Mathematics
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Ancient Egyptians are known to have understood difficult concepts in mathematics. The ancient Egyptian mathematician Ahmes liked to write a kind of arithmetic expressions on papyrus paper which he called as Ahmes arithmetic expression.

An Ahmes arithmetic expression can be defined as:

  • "d" is an Ahmes arithmetic expression, where d is a one-digit positive integer;
  • "(E1op E2)" is an Ahmes arithmetic expression, where E1 and E2 are valid Ahmes arithmetic expressions (without spaces) and op is either plus ( + ) or minus ( - ).
For example 5, (1-1) and ((1+(2-3))-5) are valid Ahmes arithmetic expressions.

On his trip to Egypt, Fafa found a piece of papyrus paper having one of these Ahmes arithmetic expressions written on it. Being very ancient, the papyrus piece was very worn out. As a result, all the operators were erased, keeping only the numbers and the brackets. Since Fafa loves mathematics, he decided to challenge himself with the following task:

Given the number of plus and minus operators in the original expression, find out the maximum possible value for the expression on the papyrus paper after putting the plus and minus operators in the place of the original erased operators.

Input

The first line contains a string E (1 ≤ |E| ≤ 104) — a valid Ahmes arithmetic expression. All operators are erased and replaced with '?'.

The second line contains two space-separated integers P and M (0 ≤ min(P, M) ≤ 100) — the number of plus and minus operators, respectively.

It is guaranteed that P + M =  the number of erased operators.

Output

Print one line containing the answer to the problem.

Examples
Input
Copy
(1?1)
1 0
Output
2
Input
Copy
(2?(1?2))
1 1
Output
1
Input
Copy
((1?(5?7))?((6?2)?7))
3 2
Output
18
Input
Copy
((1?(5?7))?((6?2)?7))
2 3
Output
16
Note
  • The first sample will be (1 + 1)  =  2.
  • The second sample will be (2 + (1 - 2))  =  1.
  • The third sample will be ((1 - (5 - 7)) + ((6 + 2) + 7))  =  18.
  • The fourth sample will be ((1 + (5 + 7)) - ((6 - 2) - 7))  =  16.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值