P7725 珍珠帝王蟹 (Crab King) 题解
P7725 珍珠帝王蟹 (Crab King) 题解
简要题意:
给定 \(n\) 个形如 \(+v\) 或 \(\times v\) 的操作以及初始数 \(0\),问怎样安排操作顺序能使最后的结果最大,输出其对 \(998244353\) 取模的结果。
数据范围:\(n\leq 10^5,2\leq \left|v\right|\leq 10^6\)
Subtask 1
\(O(n!)\) 枚举操作顺序,暴力判断最大值即可,注意到最大值不会超过 \(5^9=1953125\),所以不必考虑溢出。
Subtask 2
对于 \(v>0\) 的情况,假设我们已经得到了一个中间值 \(w\),考虑两个操作 \(+m\) 和 \(\times n\),怎样安排顺序才能最大化结果?
先加再乘:\((w+m)n=wn+mn\)
先乘再加:\(wn+m\)
显然先加、再乘是优于先乘、再加的。
所以总体的操作顺序就是先加、再乘正数。
Subtask 3
对于所有乘法操作保证 \(v>0\),即在 Subtask 2 的基础上多出了减法操作。
那么如何让减法对最后的结果影响最小?
首先,乘法要放在加法之后,才能保证其结果更优。
其次,减法不能在乘法或加法之前,不然会让乘法增大减法对答案的影响。
所以先加、再乘正数、最后减是最优方案。
Subtask 4
对于所有加法操作保证 \(v>0\),即在 Subtask 2 的基础上多出了乘负数的操作。
不会真有人还不知道负负得正吧。
如果乘负数的操作有偶数个,就和 Subtask 2 类似,只需要先加、再乘负数和正数即可。
那如果乘负数的操作有奇数个呢?
样例 \(1\) 的说明提示我们,可以在第一次操作前,把 \(0\) 乘上一个负数,这样就相当于让这个操作 “凭空消失” ,剩下的就和上面一致了。
Subtask 5
其实和上面的分析类似,我们需要考虑的就是如何让减法和乘负数对结果的影响最小 (或者说是对结果的贡献最大) 。
但是乘负数的操作数的奇偶性也会对顺序有影响。
所以按乘负数的操作数的奇偶进行分类。
- 乘负数的操作数是奇数。
不妨设有 \(2k+1\) 个操作。
对于减法操作来说,只需要让它们之和乘奇数个负数就能变成正数。
最优解是先减、再乘负数、再加、最后乘正数?显然还有更优的做法。
对于乘 \(2k\) 个较小的负数而言,他们是可以当作乘 \(2k\) 个较大的正数,而剩下的一个最大的负数就已经可以把减出来的负数变为正数了。
所以最优解应该是先减、再乘最大的负数、再加、最后乘剩下的负数和正数。
- 乘负数的操作数是偶数。
实话实说,比赛时这种情况卡了我很久。
一开始想的是跟奇数类似,再加上 Subtask 4 中先乘最大的负数的操作,也就是:
先乘最大的负数、再减、再乘第二大的负数、再加、再乘剩下的负数和正数。
但是提交之后发现这并不是正解。
思考一下:为什么我们在上一种情况中要把负数变成正数后再计算?
- \(2k\) 个乘负数的操作能乘出一个正数,但是我们有 \(2k+1\) 个。
- 而且这多出来的一个操作刚好能让减出来的负数变成正数。
那我们现在有 \(2k\) 个操作,是不是也可以让他多出来一个呢?
相信大家看到这里都能基本理解我的意思了,这里的操作与上一种情况基本相反。
既然我们想要剩下 \(2k-1\) 个乘负数的操作,我们就要让之前的所有操作得到的结果变成一个最小的负数。
所以最优解实际上是先加、再乘最大的负数、再减 (这里得到了最小的负数) 、最后乘剩下的负数和正数。
然而现在就对了吗?
对于 Subtask 3 (没有乘负数操作) 的情况,它的操作数确实是偶数,但我们得不到想要的最小负数,所以实际上这个做法只适用于操作数 \(\geq 2\) 的情况,对于操作数 \(=0\) 的情况,只需要特判并采用 Subtask 3 的做法即可。
原文地址:https://www.cnblogs.com/blueqwq/p/15012757.html
- 【swift学习笔记】四.swift使用Alamofire和swiftyJson
- 【swift学习笔记】五.使用枚举优雅的管理Segue
- 【swift学习笔记】六.访facebook登录页面
- Docker Stack 部署web集群
- Docker部属Nsq集群
- Go 单例模式[个人翻译]
- 详解go语言的array和slice 【一】
- 详解go语言的array和slice 【二】
- node.js 事件循环
- 一个实现批量抓取淘女郎写真图片的爬虫
- 计算机程序的思维逻辑 (8) - char的真正含义
- 搭建Docker私有仓库--自签名方式
- 详解JavaScript闭包
- Python多进程抓取全国邮政编码和长途区号
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Hold Time违例,该如何解决
- Tensorflow BN详解:4_使用tf.nn.batch_normalization实现BN
- Tensorflow BatchNormalization详解:3_使用tf.layers高级函数来构建带有BN的神经网络
- 【DB宝17】使用mysqldump+mysqlbinlog恢复误删除的数据库
- 13-3 vi编辑模式和移动光标
- Tensorflow BatchNormalization详解:2_使用tf.layers高级函数来构建神经网络
- 使用 numpy 切分训练集和测试集
- 反向学习,相对基学习 opposition-based learning 简介
- python获取指定目录下所有文件名os.walk和os.listdir
- 腾讯地图SDK实现点击建筑显示围栏及建筑信息效果
- 【pyspark】parallelize和broadcast文件落盘问题
- 终于知道Kafka为什么这么快了!
- 使用 L2 正则化和平均滑动模型的 LeNet-5MNIST 手写数字识别模型
- Tensorboard 监控指标可视化
- 持久化的基于 L2 正则化和平均滑动模型的 MNIST 手写数字识别模型