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

题解:P4447 [AHOI2018初中组] 分组

P4447 [AHOI2018初中组] 分组

题目描述

小可可的学校信息组总共有 nnn 个队员,每个人都有一个实力值 aia_iai。现在,一年一度的编程大赛就要到了,小可可的学校获得了若干个参赛名额,教练决定把学校信息组的 nnn 个队员分成若干个小组去参加这场比赛。

但是每个队员都不会愿意与实力跟自己过于悬殊的队员组队,于是要求分成的每个小组的队员实力值连续,同时,一个队不需要两个实力相同的选手。举个例子:[1,2,3,4,5][1, 2, 3, 4, 5][1,2,3,4,5] 是合法的分组方案,因为实力值连续;[1,2,3,5][1, 2, 3, 5][1,2,3,5] 不是合法的分组方案,因为实力值不连续;[0,1,1,2][0, 1, 1, 2][0,1,1,2] 同样不是合法的分组方案,因为出现了两个实力值为 111 的选手。

如果有小组内人数太少,就会因为时间不够而无法获得高分,于是小可可想让你给出一个合法的分组方案,满足所有人都恰好分到一个小组,使得人数最少的组人数最多,输出人数最少的组人数的最大值。

注意:实力值可能是负数,分组的数量没有限制。

输入格式

输入有两行:

第一行一个正整数 nnn,表示队员数量。

第二行有 nnn 个整数,第 iii 个整数 aia_iai 表示第 iii 个队员的实力。

输出格式

输出一行,包括一个正整数,表示人数最少的组的人数最大值。

输入输出样例 #1

输入 #1

7
4 5 2 3 -4 -3 -5

输出 #1

3

说明/提示

样例解释

分为 222 组,一组的队员实力值是 [4,5,2,3][4, 5, 2, 3][4,5,2,3],一组是 [−4,−3,−5][-4, -3, -5][4,3,5],其中最小的组人数为 333,可以发现没有比 333 更优的分法了。

数据范围

对于 100%100\%100% 的数据满足:1≤n≤1051\leq n\leq 10^51n105∣ai∣≤109|a_i|\leq10^9ai109

本题共 101010 个测试点,编号为 1∼101\sim10110,每个测试点额外保证如下:

测试点编号数据限制
1∼21\sim212n≤6,1≤ai≤100n\leq 6, 1\leq a_i \leq 100n6,1ai100
3∼43\sim434n≤1000,1≤ai≤105n\leq 1000, 1\leq a_i\leq 10^5n1000,1ai105aia_iai 互不相同
5∼65\sim656n≤105n\leq 10^5n105aia_iai 互不相同
7∼87\sim878n≤105,1≤ai≤105n\leq 10^5, 1\leq a_i \leq10^5n105,1ai105
9∼109\sim 10910n≤105,−109≤ai≤109n\leq 10^5, -10^9 \leq a_i \leq 10^9n105,109ai109
/*
思路一:
我们肯定要让分出的组数尽可能少
那么,我们考虑对于一个数x,它最理想的情况一定是放到一个结尾为x-1的组中;如果没有就只能新开一组
因为有大小顺序的限制,那么考虑首先升序排序,再用set存储当前每个组的结尾元素,每遇到一个数就在set中查找/更新即可
set要存两个信息:组的结尾元素和长度,排序规则按照先结尾元素升序,后长度升序(长度升序可以使最小长度更大)
答案就是set中长度最小的组
注意到组可以重复,所以应该用multiset
本质上是一个贪心+模拟的做法-------------------------------------------------------------------------------------------------------------------------思路二:究极数形结合
我们如果画一条数轴,那么题目说的分组,就相当于在数轴上选一个连续段:******   ********     
---------------------------------->-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7  如果数字条件变复杂(同一个值的数字会有多个),我们考虑用类似条形统计图的方式来刻画:
*           *
*      *    *    *
*   *  *    *    *       *
------------------------------->
-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 我们如果当一段被选择后就删除这些数所对应的*,那么如果这个数出现了不止一次,在它上面的*会由于重力作用落下来(???),从而支持我们继续操作
我们发现,最优策略不是看连续段越长越好,而是这样的(不同字母代表不同分组):CB B
A A A A C
这种方法不会导致最上面的C被孤立,而会和下面两个B平均起来,最终分组大小都是2可以总结出分组选择的方式:
如果右边一列的高度不低于当前列,则继续加入右边一列最下方的数。反之,停止连续选择。
这样,最靠左的一个“峰”相较其右边一列的高度差就不断减小,直到相同。如此反复。记录所画所有线的最短长度,即为答案。
可以用 std::map 关键字自动排序的特性来记录图形。正确性比较显然 (吗?)参考 https://www.luogu.com.cn/article/6bk13dsc
*/#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;int n, a[maxn];void solve()
{cin >> n;for(int i = 1; i <= n; i ++){cin >> a[i];}sort(a + 1, a + n + 1); // 注意排序multiset<pair<int, int>> s; // first:结尾元素 second:当前长度for(int i = 1; i <= n; i ++){if(s.empty()){ // 注意判空s.insert({a[i], 1}); continue;}auto it = s.lower_bound({a[i] - 1, 0});if(it == s.end() || it->first != a[i] - 1){ // 查找失败s.insert({a[i], 1});}else{s.insert({a[i], it->second + 1}); // 查找成功s.erase(it);}}int minn = 1e9;for(auto it : s){minn = min(minn, it.second);}cout << minn << '\n';
}map<int, int> vis;void solve2()
{cin >> n;for(int i = 1; i <= n; i ++){int x; cin >> x; vis[x] ++; // 初始化}int ans = 1e9;while(!vis.empty()){auto it = vis.begin(); // 取出当前最小的元素if(it->second == 0){vis.erase(it); continue; // 如果已经没了,就删掉它,并继续}int cnt = 1;while(next(it) != vis.end() && next(it)->first == it->first + 1 && next(it)->second >= it->second){ // 要满足:存在next(it)、大小是连续的、下一个的高度不低于当前列(说过的可以继续延伸的条件)cnt ++; it = next(it);}ans = min(ans, cnt);it = vis.begin();for(int i = 1; i <= cnt && it != vis.end(); i ++, it = next(it)){ // 把成功延伸的部分个数减一it->second --;}}cout << ans << '\n';
}signed main()
{ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);solve();
//	solve2();return 0;
}
```|
http://www.lryc.cn/news/607929.html

相关文章:

  • rabbitmq消息队列详述
  • python创建一个excel文件
  • PHP 与 MySQL 详解实战入门(2)
  • Removing Digits(Dynamic Programming)
  • 【第三章】变量也疯狂:深入剖析 Python 数据类型与内存原理
  • Android13文件管理USB音乐无专辑图片显示的是同目录其他图片
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博舆情数据可视化分析-热词情感趋势柱状图
  • 机器学习 —— 决策树
  • 从C++0基础到C++入门(第十五节:switch语句)
  • 计算机网络:为什么IPv6没有选择使用点分十进制
  • 如何修复非json数据
  • Gemini CLI
  • 深入 Go 底层原理(五):内存分配机制
  • 操作系统-lecture5(线程)
  • Vue3核心语法基础
  • 【大模型入门】3.从头实现GPT模型以生成文本
  • 相对路径 绝对路径
  • UniappDay07
  • sqli-labs:Less-19关卡详细解析
  • Qt 槽函数被执行多次,并且使用Qt::UniqueConnection无效【已解决】
  • 24黑马SpringCloud的Docker本地目录挂载出现相关问题解决
  • Tushare对接OpenBB分析A股与港股市场
  • 解锁智能油脂润滑系统:加速度与温振传感器选型协同攻略
  • 深度学习核心:卷积神经网络 - 原理、实现及在医学影像领域的应用
  • 【Java】在一个前台界面中动态展示多个数据表的字段及数据
  • 定制开发开源AI智能名片S2B2C商城小程序的特点、应用与发展研究
  • 自进化智能体综述:通往人工超级智能之路
  • SpringBoot IOC
  • C++之vector类的代码及其逻辑详解 (中)
  • 【自动化运维神器Ansible】YAML语法详解:Ansible Playbook的基石