P6033 [NOIP2004 提高组] 合并果子 加强版 题解
时间:2021-07-30
本文章向大家介绍P6033 [NOIP2004 提高组] 合并果子 加强版 题解,主要包括P6033 [NOIP2004 提高组] 合并果子 加强版 题解使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
我们先解决弱化版,即 P1090 ,对于 \(n \leq 10^5\) 的数据,如何解决?
很明显我们可以采取贪心,对于 \(a \leq b \leq c\),我们应先将 \(a,b\) 先合并,再与 \(c\) 合并。具体证明:
先并 \(a,b\):\((a+b)+(a+b+c)\),而其余答案为 \((a+c)+(a+b+c)\) 或 \((b+c)+(a+b+c)\),均比其劣。于是可说明,每次把两个最小的并,总是最优的。并完之后我们需要把 \(a+b\) 丢到数组里,再重新排序。
当然我们不需要每次都重新排序。可以用插入排序维护,或者更方便地用优先队列维护,时间复杂度均为 \(\mathcal{O}(n \log n)\).
强化版(即本题),如何解决?
考虑到,由于 \(a_i \leq 10^5 (\forall i \in [1,n])\),因此可以用桶排序来进行线性的排序。然后主要是如何维护 \(a+b\) 的位置?
考虑把排序过后的原数列放在一个队列(非优先队列)\(q1\) 中,把由于合并产生的数放在另一个队列 \(q2\) 中。每次从两个队列中挑出最小值和次小值将其踢出,然后再放到 \(q2\) 中。由于每次合并的总是当前最小的,因此 \(q2\) 满足单调性。\(q1\) 显然满足单调性,因此可保证正确。
时间复杂度:\(\mathcal{O}(n)\).
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e7+1;
inline int read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}
inline void write(int x) {
if(x<0) {putchar('-');write(-x);return;}
if(x<10) {putchar(char(x%10+'0'));return;}
write(x/10);putchar(char(x%10+'0'));
}
int n,a[N],h[N];
ll ans=0;
queue<ll> q1,q2;
int main() {
n=read();
for(int i=1;i<=n;i++) h[read()]++;
for(int i=1;i<=100000;i++)
for(int j=1;j<=h[i];j++) q1.push(i);
for(int i=1;i<n;i++) {
ll x,y;
if(q2.empty() || !q1.empty() && q1.front()<q2.front()) x=q1.front(),q1.pop();
else x=q2.front(),q2.pop();
if(q2.empty() || !q1.empty() && q1.front()<q2.front()) y=q1.front(),q1.pop();
else y=q2.front(),q2.pop();
ans+=x+y; q2.push(x+y);
} printf("%lld\n",ans);
return 0;
}
简易的代码胜过复杂的说教。
原文地址:https://www.cnblogs.com/bifanwen/p/15081197.html
- phalcon-入门篇3(优美的URL与Config)
- 数据库中间件 Sharding-JDBC 源码分析 —— 事务(一)之BED
- 熔断器 Hystrix 源码解析 —— 命令执行(二)之执行隔离策略
- phalapi-入门篇4(国际化高可用和自动生成文档)
- 用JavaScript动态输出的JS脚本不能执行
- Dubbo源码解析 —— 服务暴露原理
- [Golang软件推荐] RSA公私钥加解密(解决Golang私钥加密公钥解密问题)
- [喵咪大数据]Hive+Hbase关联
- 再战子域共享Cookie问题
- [喵咪大数据]Presto查询引擎
- 如何在5分钟内做出你的第一个开源贡献
- [喵咪大数据]HUE大数据管理工具
- Dubbo源码解析 —— Zookeeper 订阅
- 注册中心 Eureka 源码解析 —— 项目结构简介
- 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 数组属性和方法
- Sliding Window - 340. Longest Substring with At Most K Distinct Characters
- Sliding Window - 3. Longest Substring Without Repeating Characters
- Sliding Window - 30. Substring with Concatenation of All Words
- Sliding Window - 76. Minimum Window Substring
- GET和POST的区别
- String - 68. Text Justification
- String - 273. Integer to English Words
- String - 12. Integer to Roman
- Dynamic Programming - 62. Unique Paths
- Dynamic Programming - 70. Climbing Stairs
- LinkedList - 23. Merge k Sorted Lists
- LinkedList - 86. Partition List
- LinkedList - 148. Sort List
- LinkedList - 61. Rotate List
- LinkedList - 143. Reorder List