【NOIP】普及组2011 表达式的值
【算法】动态规划+后缀表达式
【题解】
先把算式转为后缀表达式后进行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 表达式的值的更多相关文章
- NOIP 普及组 2013 表达式求值
传送门 https://www.cnblogs.com/violet-acmer/p/9898636.html 题解: 哇哇哇,又是一发暴力AC. 用字符数组存储表达式. 然后将表达式中的 数字 与 ...
- [NOIP普及组2011]装箱问题
目录 链接 博客链接 题目链接 题目内容 题目描述 格式 输入 输出 样例 输入 输出 前缀知识 题解 题目名称:装箱问题 来源:2011年NOIP普及组 链接 博客链接 CSDN 洛谷博客 题目链接 ...
- NOIP2013普及组 T2 表达式求值
OJ地址:洛谷P1981 CODEVS 3292 正常写法是用栈 #include<iostream> #include<algorithm> #include<cmat ...
- [NOIp普及组2011]瑞士轮
洛谷题目链接:瑞士轮 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较 ...
- 数字反转 NOIp普及组2011
当数字位数不确定时,如何反转呢? 本文为博客园ShyButHandsome原创作品,转载请注明出处 使用右侧目录快速浏览文章 题目描述 给定一个整数,请将该数各个位上数字反转得到一个新数. 新数也应满 ...
- 2016.8.15上午纪中初中部NOIP普及组比赛
2016.8.15上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1333 这次比赛不怎么好,因为这套题目我并不是很擅长. 可同学们 ...
- 2016.8.17上午纪中初中部NOIP普及组比赛
2016.8.17上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1335 本来觉得自己能考高分,但只得160分,并列第九.至少又挤 ...
- 2016.9.24初中部上午NOIP普及组比赛总结
2016.9.24初中部上午NOIP普及组比赛总结 2016.09.24[初中部 NOIP普及组 ]模拟赛 其实这次我没比赛,早上去参加亲子活动去了. 不过在下午我做完了所有的题,感觉还好. 进度 现 ...
- 2321. 【NOIP普及组T1】方程
2321. [NOIP普及组T1]方程 时间限制: 1000 ms 空间限制: 262144 KB 题目描述
随机推荐
- DAY4敏捷冲刺
站立式会议 工作安排 (1)服务器配置 已完成对微信小程序登录凭证储存至云端数据库,计划使用微信接口返回的session_id进行转化返回本地,以保持登录态. (2)数据库配置 单词学习记录+用户信息 ...
- UVA725 Division (暴力求解法入门)
uva 725 Division Write a program that finds and displays all pairs of 5-digit numbers that between t ...
- scrapy(1)——scrapy介绍
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中.所谓网络爬虫,就是一个在网上到处或定向抓取数据的程序,当然,这种说 ...
- lintcode-191-乘积最大子序列
191-乘积最大子序列 找出一个序列中乘积最大的连续子序列(至少包含一个数). 样例 比如, 序列 [2,3,-2,4] 中乘积最大的子序列为 [2,3] ,其乘积为6. 标签 子数组 领英 动态规划 ...
- 微信小程序wx.pageScrollTo的替代方案
wx.pageScrollTo这个微信小程序的api功能如下: 简而言之就是实现页面滚动的.但是在实际应用当中显得有些鸡肋,为啥呢?使用中有明显页面有明显的抖动,这无疑是极不好的用户体验.我用的华为6 ...
- CentOS基础命令
为网卡配置静态IP地址建议通过交互式界面nmtui进行配置 firewalld和iptablesCentOS7使用firewald取代原来的iptables,但实际上底层还是iptables,在上层加 ...
- Windows2008安装启用无线网卡
昨天给本子换了系统来着,本来想法是好的,想在本子上安装Hyper-v来搭建多平台VPS,这样的话就能玩多个系统了,对于我自己来说对娱乐没啥兴趣,扯多了,正文 笔记本安装什么都很顺利,但是无线网卡把我难 ...
- SpringBoot2.0(五) CORS跨域
部分跨域 @CrossOrigin注解支持类级别,方法级别添加.可以在controller类或者方法上添加,支持部分接口跨域.在两者上都添加时,方法级别的覆盖类级别的. 属性 说明 origins 允 ...
- 【Python】python基础_代码编写注意事项
1. 说明使用的编译方式 1 #!/usr/bin/python 2. 说明字符编码方式 1 #coding=utf-8 3. print 默认输出是换行的,如果要实现不换行需要在变量末尾加上逗号 # ...
- Luogu1092 NOIP2004虫食算(搜索+高斯消元)
暴力枚举每一位是否进位,然后就可以高斯消元解出方程了.然而复杂度是O(2nn3),相当不靠谱. 考虑优化.注意到某一位进位情况的变化只会影响到方程的常数项,于是可以在最开始做一次高斯消元算出每个未知数 ...