1. 程式人生 > 實用技巧 >洛谷 P1310 表示式的值(棧+DP)

洛谷 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程式碼