【算法】动态规划+后缀表达式

【题解】

先把算式转为后缀表达式后进行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.对符号设置优先级,即先计算的符号,一般是 () > * > + 。

2.从前往后扫描,遇到数字入数字栈顶,遇到符号入符号栈顶。

如果当前符号优先级低于栈顶符号,那么弹出栈顶符号并对数字栈顶和次顶弹出做该符号运算,结果重新作为数字栈顶。

重复直至优先级高于栈顶符号或栈空。

3.遇到左括号直接入栈,遇到右括号弹出符号栈顶直至左括号停止。

为了最后能清空符号栈,通常最开始加入左括号,最后加入右括号。

4.本题的DP其实是对数字栈DP,每次运算时对应变换DP数组f[]。

我的代码中的写法是先处理出后缀表达式(数字直接放,符号压栈),然后再用后缀表达式模拟数字栈变化。

【注意】

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=,mod=;
char s[maxn*],t[maxn*],now[maxn*],c;
int lenn,lent,len,num,n;
int f[maxn][];
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][]=(f[num][]*f[num+][]+f[num][]*f[num+][]+f[num][]*f[num+][])%mod;
f[num][]=(f[num][]*f[num+][])%mod;
}
void cheng()
{
f[num][]=(f[num][]*f[num+][]+f[num][]*f[num+][]+f[num][]*f[num+][])%mod;
f[num][]=(f[num][]*f[num+][])%mod;
}
void change()
{
now[]='(';lenn=;lent=-;
for(int i=;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=;
for(int i=;i<=lent;i++)
{
if(t[i]=='_')
{
num++;
f[num][]=;f[num][]=;
}
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=-;
if(c!='(')s[]='_',len=;
s[++len]=c;
for(int i=;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[][]);
return ;
}

【NOIP】普及组2011 表达式的值的更多相关文章

  1. NOIP 普及组 2013 表达式求值

    传送门 https://www.cnblogs.com/violet-acmer/p/9898636.html 题解: 哇哇哇,又是一发暴力AC. 用字符数组存储表达式. 然后将表达式中的 数字 与 ...

  2. [NOIP普及组2011]装箱问题

    目录 链接 博客链接 题目链接 题目内容 题目描述 格式 输入 输出 样例 输入 输出 前缀知识 题解 题目名称:装箱问题 来源:2011年NOIP普及组 链接 博客链接 CSDN 洛谷博客 题目链接 ...

  3. NOIP2013普及组 T2 表达式求值

    OJ地址:洛谷P1981 CODEVS 3292 正常写法是用栈 #include<iostream> #include<algorithm> #include<cmat ...

  4. [NOIp普及组2011]瑞士轮

    洛谷题目链接:瑞士轮 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较 ...

  5. 数字反转 NOIp普及组2011

    当数字位数不确定时,如何反转呢? 本文为博客园ShyButHandsome原创作品,转载请注明出处 使用右侧目录快速浏览文章 题目描述 给定一个整数,请将该数各个位上数字反转得到一个新数. 新数也应满 ...

  6. 2016.8.15上午纪中初中部NOIP普及组比赛

    2016.8.15上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1333 这次比赛不怎么好,因为这套题目我并不是很擅长. 可同学们 ...

  7. 2016.8.17上午纪中初中部NOIP普及组比赛

    2016.8.17上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1335 本来觉得自己能考高分,但只得160分,并列第九.至少又挤 ...

  8. 2016.9.24初中部上午NOIP普及组比赛总结

    2016.9.24初中部上午NOIP普及组比赛总结 2016.09.24[初中部 NOIP普及组 ]模拟赛 其实这次我没比赛,早上去参加亲子活动去了. 不过在下午我做完了所有的题,感觉还好. 进度 现 ...

  9. 2321. 【NOIP普及组T1】方程

    2321. [NOIP普及组T1]方程 时间限制: 1000 ms  空间限制: 262144 KB 题目描述

随机推荐

  1. 自学系列--git的基础简介

    上学期第一次接触git,感觉挺难的,我们都知道这个非常重要,自己对git也自学了一段时间,下面这是对自学内容的总结,拿出来和大家一块交流一下,让我们一起成长吧! 一 git简介 Git是一个开源的分布 ...

  2. 第一周—Fortran语言学习

    使用教材:Fortran95程序设计[彭国伦] 第二章 编译器的使用 编译结果的好坏 1.翻译正确 2.执行文件的运行效率 3.翻译出来的执行码的长短 4.编译过程花费的时间 5.编译器提供Debug ...

  3. TCP系列10—连接管理—9、syncookie、fastopen与backlog

    这部分内容涉及较多linux实现,可以跳过. 一.listen系统调用对backlog的处理 当socket处于LISTEN或者CLOSED状态时,fastopen队列的长度可以通过TCP_FASTO ...

  4. Personal summary 个人总结

    一.请回望开学时的第一次作业,你对于软件工程课程的想象 对比开篇博客你对课程目标和期待,"希望通过实践锻炼,增强计算机专业的能力和就业竞争力",对比目前的所学所练所得,在哪些方面达 ...

  5. PAT L1-048 矩阵A乘以B

    https://pintia.cn/problem-sets/994805046380707840/problems/994805082313310208 给定两个矩阵A和B,要求你计算它们的乘积矩阵 ...

  6. xpath教程三---逐层检索和全局检索

    本节主要介绍用xpath来描述html的层级关系 主要使用到的知识点如下: 单独的一个点 .,表示当前位置 两个点 ..,表示上一级父标签的位置 单独的一个斜杠 /,表示只检索下面一级 单独的两个斜杠 ...

  7. mysql8基本配置,差点被各种坑蒙圈

    1. 下载免安装版mysql地址 https://dev.mysql.com/downloads/mysql/ 2. 基本配置 (1)解压zip包,将bin目录添加到环境变量 (2)在mysql根目录 ...

  8. 检测固定IP的端口是否开放批出

    因为运维工作经常需要telnet某个IP的端口是否正常,因此有了下文 .BAT内容如下: @echo off for /f %%i in ('type ip.txt') do ( echo %%i t ...

  9. VBA 实现学校上课教员一学期中所有上课时间,在一页中通过背景底色反应出来

    需求:学校一学期的所有课程表,每个教员都有可能上好几门课,但给一个教员调课时需要查找所调课时间位置有没有此教员上其它的课 相冲突,手动查找很不方便,这里想通过一个表中位置显示出同一教员在所有课表中出现 ...

  10. Luogu1041 NOIP2003传染病控制(搜索)

    暴搜加个最优性剪枝即可.一直觉得正式比赛出这种不能一眼看出来暴搜就行了的搜索题的出题人都是毒瘤. #include<iostream> #include<cstdio> #in ...