当前位置: 首页 > ds >正文

1083. 数列极差问题

题目描述

在黑板上写了NNN个正整数组成的一个数列,进行如下操作: 每次擦去其中的两个数 ab ,然后在数列中加入一个数a×b+1a \times b+1a×b1,如此下去直至黑板上 剩下一个数,在所有按这种操作方式最后得到的数中,最大的为 maxmaxmax,最小的为 minminmin , 则该数列的极差定义为 M=max-minM=max-minMmaxmin
请你编程,对于给定的数列,计算极差 mmm

输入

第一行是数列的长度n(不超过10),第二行起是数列中n个数,相邻2个数由空格分开;
每个数均不超过100.

输出

输出一个整数表示数列极差m

样例输入

3
1  2  3

样例输出

2

思路

题目中有这个东西: 每次 擦去 其中的两个数 aaabbb,然后在数列中加入一个数 a×b+1a \times b+1a×b1

这不就是哈夫曼编码的建立过程吗? 所以我们根据贪心策略,当然每次选择最小的整数相乘自然会更好呀?

什么? 你想要证明?这个和哈夫曼编码的证明的方法是一样的,最好的方法当然是上网搜索啦 (其实太复杂了,作者不会qwq)

Step1: 定义堆

priority_queue<int> q1;
priority_queue<int, vector<int>, greater<int>> q2;

q1 里面的元素是越大的在前面,q2 就是越小的在前面
注意: q2的定义后面的两个 “>>” 符号在编译的时候要使用 C++11 编译,要使用 C++11 提交,如果不想这样,可以加一个空格,比如:

priority_queue<int, vector<int>, greater<int> > q2;

Step2: 主程序计算

int Max = 0, Min = 0;
while (q1.size() > 1)
{int p = q1.top(); q1.pop();int q = q1.top(); q1.pop();	q1.push(p * q + 1);
}
Min = q1.top();while (q2.size() > 1)
{int p = q2.top(); q2.pop();int q = q2.top(); q2.pop();q2.push(p * q + 1);
}
Max = q2.top();printf("%d", Max - Min);

push: 表示将元素 i 插入堆
pop: 表示删除最大/最小的元素
top: 表示取最大的元素

Step3: 完整代码

#include <stdio.h>
#include <queue>using namespace std;int n;
priority_queue<int> q1;
priority_queue<int, vector<int>, greater<int>> q2;
int main()
{int n;scanf("%d", &n);for (int i = 1; i <= n; i++){int x;scanf("%d", &x);q1.push(x), q2.push(x);}int Max = 0, Min = 0;while (q1.size() > 1){int p = q1.top(); q1.pop();int q = q1.top(); q1.pop();q1.push(p * q + 1);}Min = q1.top();while (q2.size() > 1){int p = q2.top(); q2.pop();int q = q2.top(); q2.pop();q2.push(p * q + 1);}Max = q2.top();printf("%d", Max - Min);return 0;
}

时间复杂度分析

堆的 pushO(log⁡n)O(\log n)O(logn) 的,但是这道题的数列的长度是 101010, 完全足够
运行时间只有 0.1s0.1s0.1s, 因为机器的每秒钟运算大概是 10810^8108, 0.1s0.1s0.1s 大约就是 10710^7107 左右,那么这个程序的时间复杂度是 O(nlog⁡n)O(n \log n)O(nlogn) 在最大规模是 101010 的情况下大约要进行 303030 次运算(太快了,oj 上跑出了 0ms0 ms0ms)

http://www.xdnf.cn/news/18164.html

相关文章:

  • duiLib 实现鼠标拖动标题栏时,窗口跟着拖动
  • K8s核心组件全解析
  • 产品设计.原型设计
  • 嵌入式 Linux LED 驱动开发实验
  • SpringBoot 整合 Langchain4j:系统提示词与用户提示词实战详解
  • EP1C12F324I7N Altera Cyclone FPGA
  • Python 读取 CSV 文件并删除前五列
  • [安洵杯 2019]Attack
  • Win11更新0x80073712错误解决方法
  • Java 中重载与重写的全面解析(更新版)
  • vscode的使用
  • 10.从开始写LINUX内核——时钟中断
  • 12分区南排烟机,多线模块没电
  • nflsoi 8.16 题解
  • day42_2025-08-16
  • Windows MCP.Net:基于.NET的Windows桌面自动化MCP服务器深度解析
  • 第3章现象表:比较顺序表和链表
  • 记录 GMS 认证相关条件
  • Leetcode 14 java
  • A*寻路算法:原理、实现与优化指南
  • 【Java笔记】synchronized
  • SpringBoot学习日记(九)
  • 游戏客户端性能测试总结
  • 【渗透实战】无下载器环境(curl/wget)下玩转 Metasploit 自动利用
  • [创业之路-550]:公司半年度经营分析会 - 解决方案汇总
  • “preinstall“: “npx only-allow pnpm“
  • WrenAI部署,解决发送消息报错:failed to create asking task
  • Day15 Docker
  • Java设计模式详细解读
  • uv - 基本使用