【算法】动态规划+后缀表达式
【题解】
先把算式转为后缀表达式后进行DP
令f[s][0]表示使表达式答案为0的方案数
f[s][1]表示使表达式答案为1的方案数
(加法)
f[a+b][1]=f[a][0]*f[b][1]+f[a][1]*f[b][0]+f[a][1]*f[b][1]
f[a+b][0]=f[a][0]*f[b][0]
(乘法)
f[a+b][0]=f[a][0]*f[b][0]+f[a][0]*f[b][1]+f[a][1]*f[b][0]
f[a+b][1]=f[a][1]*f[b][1]
【注意】
1.记得取模10007。
2.调试几小时的教训!在计算“+”的f[a+b][1]的时候调用了f[a+b][0],所以一定要把f[a+b][1]先计算!!!(“*”反之)T_T调得好累……
#include<cstdio> #include<cmath> #include<cstring> #include<cctype> #include<algorithm> using namespace std; const int maxn=150010,mod=10007; char s[maxn*2],t[maxn*2],now[maxn*2],c; int lenn,lent,len,num,n; int f[maxn][2]; void jrz() { while(now[lenn]==‘+‘||now[lenn]==‘*‘)t[++lent]=now[lenn--]; now[++lenn]=‘+‘; } void crz() { while(now[lenn]==‘*‘)t[++lent]=now[lenn--]; now[++lenn]=‘*‘; } void kcz() { while(now[lenn]!=‘(‘)t[++lent]=now[lenn--]; lenn--; } void pluss() { f[num][1]=(f[num][0]*f[num+1][1]+f[num][1]*f[num+1][0]+f[num][1]*f[num+1][1])%mod; f[num][0]=(f[num][0]*f[num+1][0])%mod; } void cheng() { f[num][0]=(f[num][0]*f[num+1][1]+f[num][1]*f[num+1][0]+f[num][0]*f[num+1][0])%mod; f[num][1]=(f[num][1]*f[num+1][1])%mod; } void change() { now[0]=‘(‘;lenn=0;lent=-1; for(int i=0;i<=len;i++) {//printf("%d",i); //for(int j=0;j<=lenn;j++)printf("%c",now[j]); //printf(" lenn=%d\n",lenn); if(s[i]==‘_‘)t[++lent]=‘_‘; if(s[i]==‘+‘)jrz(); if(s[i]==‘*‘)crz(); if(s[i]==‘(‘)now[++lenn]=‘(‘; if(s[i]==‘)‘)kcz(); } kcz();//printf("lenn=%d",lenn);printf("[t]\n\n%s\n\n",t); } void work() { num=0; for(int i=0;i<=lent;i++) { if(t[i]==‘_‘) { num++; f[num][0]=1;f[num][1]=1; } if(t[i]==‘+‘)num--,pluss();//printf("f[%d][0]=%d,f[%d][1]=%d\n",num,f[num][0],num,f[num][1]); if(t[i]==‘*‘)num--,cheng();//printf("f[%d][0]=%d,f[%d][1]=%d\n",num,f[num][0],num,f[num][1]); } } int main() { // freopen("exp.in","r",stdin); // freopen("exp.out","w",stdout); scanf("%d",&n); c=getchar();c=getchar(); len=-1; if(c!=‘(‘)s[0]=‘_‘,len=0; s[++len]=c; for(int i=2;i<=n;i++) { c=getchar(); if(c!=‘(‘&&s[len]!=‘)‘)s[++len]=‘_‘; s[++len]=c; } if(c!=‘)‘)s[++len]=‘_‘; // printf("\n\n%s\n\n",s); change(); work(); printf("%d",f[1][0]); return 0; }
时间: 2024-10-14 02:21:51