洛谷 P1310 表达式的值(栈+DP)

题目链接:https://www.luogu.com.cn/problem/P1310

 

首先因为有优先级和括号,可以先把表达式化成后缀表达式的形式,其中用'.'表示这一个点是数字。

用u记录得到0的方案数,v记录得到1的方案数。

设两个步骤的运算结果经过每个符号到一个结果时,

第一个运算结果算出0的方案数为t1,1的方案数为t2。第二个算出0的方案数为t3,算出1的方案数为t4。

则有: 当符号是“⊕”时,得到0的方案数为t1*t3,1的方案数:t1*t4+t2*t3+t2*t4

   当符号是“×”时,得到0的方案数为t1*t3+t1*t4+t2*t3,1的方案数:t2*t4

 

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 const int N=100005;
 5 const int mod=10007;
 6 int l,top,k;
 7 char c[N],ans[N],st[N];
 8 int u[N],v[N];
 9 int main(){
10     scanf("%d",&l);
11     scanf("%s",c);
12     ans[++k]='.';
13     for(int i=0;i<l;i++){
14         if(c[i]=='('||c[i]=='*') st[++top]=c[i];
15         if(c[i]=='+'){
16             while(st[top]=='*') ans[++k]=st[top--];
17             st[++top]=c[i]; 
18         }
19         if(c[i]==')'){
20             while(st[top]!='(') ans[++k]=st[top--];
21             top--;
22         }
23         if(c[i]!='('&&c[i]!=')') ans[++k]='.';
24     }
25     while(top) ans[++k]=st[top--];
26     for(int i=1;i<=k;i++){
27         if(ans[i]=='.'){
28             u[++top]=1;
29             v[top]=1;
30         }
31         if(ans[i]=='*'){
32             top--;
33             u[top]=(u[top+1]*u[top]+v[top]*u[top+1]+u[top]*v[top+1])%mod;
34             v[top]=(v[top+1]*v[top])%mod;
35         } 
36         if(ans[i]=='+'){
37             top--;
38             v[top]=(v[top+1]*v[top]+u[top]*v[top+1]+v[top]*u[top+1])%mod;
39             u[top]=(u[top+1]*u[top])%mod;
40         }
41     }
42     printf("%d",u[1]);
43     return 0;
44 }
AC代码

 

posted @ 2020-11-02 20:05  dfydn  阅读(98)  评论(0编辑  收藏  举报