当前位置:首页 > 洛谷 > 洛谷P1323题解:优先队列与单调栈解决删数问题

洛谷P1323题解:优先队列与单调栈解决删数问题

18小时前

洛谷P1323题解:优先队列与单调栈解决删数问题 洛谷题解 优先队列 最小堆 单调栈 贪心算法 第1张

一、题目解读

洛谷P1323题要求生成前k个最小的元素,并通过删除m个数字使剩余序列单调递增。题目需结合生成算法与优化删除策略,考验对数据结构与贪心思想的运用。

二、解题思路

1. 生成最小k数:利用优先队列最小堆)维护当前最小元素。每次取出队首元素,生成其衍生元素(2x+1和4x+5),避免重复后加入队列,直至得到k个元素。

2. 删除m数优化:将生成的数字拼接为字符串,采用单调栈策略。遍历字符时,若末尾数字小于当前数字且可删除次数剩余,则弹出栈顶直至满足条件,最终保留单调递增子序列

三、解题步骤

1. 输入k和m,初始化优先队列pq(最小堆)并加入初始元素1。

2. 循环k次:

    取出队首元素,若与上一元素重复则跳过。

    加入队列的新元素为2x+1和4x+5,确保队列始终维护最小元素。

3. 将生成的k个元素拼接为字符串numStr。

4. 遍历numStr,利用单调栈删除:

    若当前字符大于栈顶且可删除次数>0,弹出栈顶直至不满足条件。

    将当前字符入栈,最终栈中序列即为删除m个数字后的最大单调递增子串。

5. 若剩余删除次数未用完,从末尾截断字符串。

6. 输出原始序列和优化后的结果。

四、代码与注释

#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    int k, m;
    cin >> k >> m; // 输入k和m
    
    // 优先队列(最小堆)生成k个最小元素
    priority_queue<int, vector<int>, greater<int>> pq;
    vector<int> elements;
    pq.push(1); // 初始元素1
    
    while(elements.size() < k) {
        int current = pq.top(); // 取出最小元素
        pq.pop();
        // 避免重复元素
        if (!elements.empty() && current == elements.back()) {
            continue;
        }
        elements.push_back(current); // 加入有效元素
        // 生成新元素加入队列
        pq.push(2 * current + 1);
        pq.push(4 * current + 5);
    }
    
    // 拼接数字为字符串
    string numStr;
    for (int num : elements) {
        numStr += to_string(num);
    }
    cout << numStr << endl; // 输出原始序列
    
    // 单调栈删除m个数字优化
    string result;
    int remove = m;
    for (char digit : numStr) {
        // 贪心删除:若当前数字比栈顶大且可删除
        while (remove > 0 &&!result.empty() && digit > result.back()) {
            result.pop_back(); // 弹出栈顶
            remove--;
        }
        result.push_back(digit); // 加入当前数字
    }
    // 剩余删除次数从末尾截断
    if (remove > 0) {
        result = result.substr(0, result.size() - remove);
    }
    cout << result << endl; // 输出优化结果
    return 0;
}

五、总结

该解法巧妙结合优先队列与单调栈:前者高效生成有序序列,后者通过贪心策略删除元素确保单调性。代码简洁且逻辑清晰,避免复杂循环,时间复杂度低。解题时需注意重复元素的判断与删除操作的边界处理,是处理此类生成+优化问题的典型范例。

原创内容 转载请注明出处

分享给朋友:

相关文章

洛谷P1007士兵过桥问题详解 C++贪心算法实现与优化

洛谷P1007士兵过桥问题详解 C++贪心算法实现与优化

题目解读这道题目描述了一座长度为L的桥上有n个士兵,每个士兵每秒可以向左或向右移动1个单位。当士兵到达桥的端点(0或L+1)时离开桥。要求计算所有士兵离开桥的最小时和最大时间。解题思路最小时计算:每个...

牛客13271题「删除K个数字的最小数」解题报告:贪心算法与栈的应用(附代码注释)

牛客13271题「删除K个数字的最小数」解题报告:贪心算法与栈的应用(附代码注释)

一、题目解读牛客13271题要求从给定的数字字符串中删除K个数字,使得剩余数字按原顺序排列后得到的最小数。题目核心在于如何在保持数字相对顺序的前提下,通过删除操作得到最优解。需注意结果字符串可能包含前...

GESP五级题巧夺大奖解题报告:贪心算法优化与代码实现(洛谷B3872)

GESP五级题巧夺大奖解题报告:贪心算法优化与代码实现(洛谷B3872)

一、题目解读2023年GESP五级题目“巧夺大奖”(洛谷B3872)是一个经典的资源分配问题。题目要求玩家在有限时间内选择多个游戏,每个游戏有截止时间和奖励值,需在截止时间前完成游戏以获得奖励。目标是...

【牛客13256题解析】贪心算法优化题目组合问题:三元组与二元组的解题思路

【牛客13256题解析】贪心算法优化题目组合问题:三元组与二元组的解题思路

一、题目解读牛客13256题要求处理一组题目难度数据,通过组合三元组(难度差≤20)或二元组(难度差≤10)来重新编排题目,计算需要补充的最小题目数量。题目本质是资源分配与优化问题,需高效组合现有题目...

2024蓝桥杯国赛B组最小字符串题解:贪心算法实战应用(洛谷P10910代码解析)

2024蓝桥杯国赛B组最小字符串题解:贪心算法实战应用(洛谷P10910代码解析)

一、题目解读题目要求给定一个长度为N的字符串S和M个待插入字符,通过将这些字符全部插入S中,构造出字典序最小的新字符串。这是典型的字符串构造问题,考察选手对贪心算法的理解和应用能力。二、解题思路采用贪...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。