P4447 [AHOI2018初中组] 分组 题解复盘

P4447 AHOI2018初中组 分组 题解复盘

模块:贪心算法

目标:将所有队员分成若干组,使人数最少的组人数最大

基本信息

项目 内容
题目编号、来源 P4447 洛谷 / AHOI2018初中组 分组
训练层级 B 贪心进阶
知识版块 贪心、排序、优先队列、状态维护

解题前・关键信号识别

维度 分析
目标、约束、底层结构 目标 :将所有队员分成若干组,使最小组的人数尽可能多。 约束 :每组实力值必须连续,并且同一个实力值不能出现在同一组。 底层结构:按照实力值排序后,从小到大处理每个数字,将当前数字加入满足条件的最短组,使各组长度尽可能均衡。
数据规模 n≤100000,需要 O(nlogn) 算法。排序和优先队列可以满足要求。
候选算法和依据 算法:排序 + 贪心 + 优先队列。 依据:处理实力值 x 时,只能加入最后一个数字为 x-1 的组;为了最大化最小组长度,应优先扩展长度最短的组。
复杂度预判 排序 O(nlogn),每个元素最多进行一次堆操作 O(logn)。 时间复杂度 O(nlogn),空间复杂度 O(n)。

解题后・外化复盘

维度 内容
实现结构 / 核心思路 第一步对所有实力值排序。第二步使用 map 保存不同结尾数字对应的所有组长度,其中优先队列维护当前最短的组。第三步遍历每个实力值 x:如果存在以 x-1 结尾的组,则取出其中长度最短的组,将 x 加入,长度增加1;否则新建一个长度为1的组。最后统计所有组长度中的最小值,即为答案。
错因回溯 1. 一开始容易认为应该优先扩展最长的组,但题目目标是让最短组最大,因此应该补短组。 2. 没有理解 map + priority_queue 的作用,需要维护不同结尾数字的组状态。 3. 使用堆时容易混淆 top()pop()top() 查看元素,pop() 删除元素。
边界和易错点 1. 实力值范围很大,不能直接开数组,需要使用 map。 2. 相同实力值不能放在同一个组,所以需要创建不同的组。 3. 当前数字只能加入以 x-1 结尾的组。 4. 扩展一个组后,需要删除旧长度,再加入新的长度。
下次看到什么信号,我应该想到这个方法 看到「分组 + 连续要求 + 最大化最小组长度」,想到:排序后维护多个组状态,用优先队列贪心分配。

AC 完整代码

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;

int main()
{
    int n;
    cin>>n;

    vector<long long> a(n);

    for(int i=0;i<n;i++)
        cin>>a[i];

    sort(a.begin(),a.end());

    map<long long,priority_queue<int,vector<int>,greater<int>>> mp;

    for(auto x:a)
    {
        if(!mp[x-1].empty())
        {
            int len=mp[x-1].top();
            mp[x-1].pop();

            mp[x].push(len+1);
        }
        else
        {
            mp[x].push(1);
        }
    }

    int ans=1e9;

    for(auto &p:mp)
    {
        while(!p.second.empty())
        {
            ans=min(ans,p.second.top());
            p.second.pop();
        }
    }

    cout<<ans;

    return 0;
}
相关推荐
SNAKEpc121381 小时前
OpenGL(十一)- 变换管线
c语言·c++·算法·矩阵·图形渲染
饼饼学习空间智能3 小时前
遥操作数据能否提升机器人自主化水平?详解模仿学习、仿真放大与Sim2Real闭环
人工智能·算法
间歇性努力持续性发呆的野生快乐选手3 小时前
dfs回溯,bfs枚举,完全背包
c++·算法·深度优先·宽度优先
嵌入式冰箱4 小时前
2026年华数杯B题完整解题思路与建模方案
算法
郝学胜_神的一滴4 小时前
干货版《算法导论》17:双数极值配对与卡牌手牌编码最优解
数据结构·算法
nike0good4 小时前
Codeforces Round 1101 (Div. 2) 题解
算法
中年阿甘4 小时前
解析式布局-二次线长布局
线性代数·算法·矩阵
程序喵大人5 小时前
【C++进阶】STL算法与函数对象 -【C++进阶】STL算法与函数对象
开发语言·c++·算法
星轨初途5 小时前
LeetCode 热题 100——day6 三数之和
数据结构·c++·算法·leetcode·职场和发展