题意:

给出一个后缀表达式,仅包含 aaa 和 +++,aaa 表示数字,+++ 表示运算符。每次可以交换表达式中的两个字符位置,也可以在任意位置插入一个 aaa 或一个 +++,要求操作完后使得原表达式变成一个合法的后缀表达式,求最少操作次数。(1≤n≤3∗106)(1\leq n\leq 3*10^6)(1≤n≤3∗106)


思路:

首先我们需要把题意理顺,怎样的表达式叫做一个合法的表达式。即对于表达式中每一个 +++ 号位置,其前缀 aaa 的和大于前缀 +++ 的和,且表达式的最后一个位置前缀 aaa 的和等于前缀 +++ 的和减 111。

我们令 aaa 为 111,令 +++ 为 −1-1−1,则对于每一个 +++ 号位置,满足前缀和大于 000,且整个序列和等于 111。

首先我们先计算出最少需要加上多少个 aaa,或者加上多少个 +++,如果需要加 +++,则放到末尾。如果需要加上 aaa,则放到开头。放好需要的 aaa 和 +++ 之和,可以满足整个序列的和为 111。

然后我们来考虑整个序列中不合法的位置,即符号为 +++,且前缀和小于等于 000。我们令这个位置变得合法,只有两种操作,一种是在这个位置之前放 111,然后在末尾添上一个 −1-1−1;或者交换这个位置和后面的那个位置。然后我们会发现在这个序列中一定有一个最小值和次小值,如果最小值和次小值都不满足要求,则我们需要至少交换两次,或者在开头位置加上 111,末尾加上 −1-1−1,则最小和次小都会 +1+1+1。

考虑到这个地方之后,我们可以发现要想让操作数最少,我们需要先通过在序列首加 aaa 使得次小值合法,然后再通过不断交换最小值和其相邻字符,令最小值也变法,这种策略就可以达到操作数最少的目的。


总结:

这是一个中等难度的贪心问题,比赛时有一个地方考虑错了,导致贪心失败,最后也没有做出来,还是较为懊悔的。

感觉自己在贪心问题上还是比较欠缺的。我觉得主要的原因还是在于一是贪心题做的少了,二是在于不会证明自己的贪心策略,而这主要也在于贪心策略比较难以求证。

如果加强自己的贪心能力呢?目前的策略就是多做一些贪心问题,多总结一些贪心思路,还是在摸索的一个过程,到底可不可行还要走一步看一步。

今天这道贪心问题的一个小得到就是关于序列字符问题,能转成数字就转成数字,因为一般人都对数字更加敏感。


代码:

#include <bits/stdc++.h>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 3000000+10;
const db EPS = 1e-9;
using namespace std;char s[N];
int sum[N];int main()
{int _; scanf("%d",&_);rep(Ca,1,_){scanf("%s",s+1);int s1 = 0, s2 = 0;int len = strlen(s+1), ans = 0, base = 0;rep(i,1,len)if(s[i] == 'a') s1++;else s2++;if(s1 > s2) ans += s1-1-s2;else ans += s2+1-s1, base += s2+1-s1;sum[0] = base;int m1 = 1, m2 = 1;rep(i,1,len){sum[i] = sum[i-1]+(s[i]=='a'?1:-1);if(s[i] == 'a') continue;if(sum[i] < m1) m2 = m1, m1 = sum[i];else if(sum[i] < m2) m2 = sum[i];}if(m2 <= 0 && m1 <= 0)ans = ans+2*(1-m2)+(m2-m1);else if(m1 <= 0)ans = ans+1-m1;printf("Case %d: %d\n",Ca,ans);}return 0;
}

【UVALive - 6922】Reverse Polish Notation【贪心】相关推荐

  1. leetcode - 150. Evaluate Reverse Polish Notation

    前言:记录一下leetcode上的一道题目: 题目网址:https://leetcode.com/problems/evaluate-reverse-polish-notation/descripti ...

  2. leetcode day1 -- Reverse Words in a String Evaluate Reverse Polish Notation Max Points on a Li

    以前从来没做过什么oj,发现做oj和在本地写代码或者纸上写差别还是很大的,觉得今天开始刷oj,特此记录一下. 1.Reverse Words in a String Given an input st ...

  3. Algorithm:C++语言实现之链表相关算法(单链公共结点问题、一般LCA、括号匹配、最长括号匹配、逆波兰表达式Reverse Polish Notation、直方图矩形面积、收集雨水问题)

    Algorithm:C++语言实现之链表相关算法(单链公共结点问题.一般LCA.括号匹配.最长括号匹配.逆波兰表达式Reverse Polish Notation.直方图矩形面积.收集雨水问题) 目录 ...

  4. Reverse Polish Notation

    http://www.1point3acres.com/bbs/thread-31595-1-1.html 定义一种叫做"Reverse Polish Notation"的表达式: ...

  5. LeetCode-150-Evaluate Reverse Polish Notation

    算法描述: Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are ...

  6. LeetCode 150. Evaluate Reverse Polish Notation

    LeetCode 150. Evaluate Reverse Polish Notation Solution1: 参考网址:http://www.cnblogs.com/grandyang/p/42 ...

  7. 计算后续表达式 LectCode之Evaluate Reverse Polish Notation

    在记录lectcode这道题目前先说明一下三个相关知识点:前序表达式,中序表达式,后序表达式 前序表达式(Polish Notation 或 Prefix Notation): 前序表达式就是不含括号 ...

  8. [LeetCode]题解(python):150-Evaluate Reverse Polish Notation

    题目来源: https://leetcode.com/problems/evaluate-reverse-polish-notation/ 题意分析: 给定一个数组,用这个数组来表示加减乘除,例如 [ ...

  9. leetcoder reverse polish notation解题笔记

    题目在这里 http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ 逆波兰表达式的求值,最简单直接的方法, 没有坑 1. 简 ...

  10. Leetcode 之Evaluate Reverse Polish Notation(41)

    很简单的一道题,定义一个栈保留操作数,遇操作符则弹出运算即可. bool isOperator(string &op){//注意用法return op.size() == 1 &&am ...

最新文章

  1. android doGet和doPost
  2. VS2010 自定义用户控件未出现在工具箱的解决方案
  3. 跨编译单元之初始化次序
  4. codevs 1147 排座椅
  5. Sharepoin学习笔记—架构系列--03 Sharepoint的处理(Process)与执行模型(Trust Model) 2
  6. template多行编写的方式
  7. 移动应用开发商的生存之道
  8. bat 等待输入_bat-批量修改文件或者文件夹名称
  9. 沉浸文化获星瀚资本百万元级种子轮投资,星瀚资本投资
  10. GDI+中发生一般性错误的解决办法(转帖)
  11. 【Python3网络爬虫开发实战】1.2.5-PhantomJS的安装
  12. python3.5安装教程linux_Linux下安装python3.6和第三方库的教程详解
  13. 实录:oracle下大表清理整改
  14. Bernoulli-Gaussian分布
  15. PDF加页码怎么设置?这里有你想知道的答案
  16. 安装python与编译工具vs code(中文版)和pycharm(中文版)
  17. 家具vr虚拟交互展示外包制作
  18. 单片机实验——0到60秒的计时器
  19. 啊哈C语言第四章99乘法表
  20. 各类通信协议归纳整理(偏硬件)

热门文章

  1. Cannot complete this action,please try again. Correlation ID :bd640a9d-4c19-doff-2fe0-6ce1104b59ae
  2. apache高性能配置
  3. 不能查看工作组计算机 提示没有权限拒绝访问
  4. 去掉jsp页面自动生成的空行
  5. STC学习:霍尔开关器件
  6. nvm nodejs npm快速安装
  7. mysql损坏打不开_mysql 断电导致表打不开解决方案
  8. mysql 分表例子_mysql分表查询的简单例子
  9. python判断整数是否对称_刷题系列 - Python判断是否镜像对称二叉树
  10. 损失函数的意义和作用_BN究竟起了什么作用?一个闭门造车的分析