当前位置:首页 > 蓝桥杯 > 洛谷P10909题(2024蓝桥杯国B):二分查找+贪心算法解决立定跳远

洛谷P10909题(2024蓝桥杯国B):二分查找+贪心算法解决立定跳远

4个月前 (08-15)

洛谷P10909题(2024蓝桥杯国B):二分查找+贪心算法解决立定跳远 洛谷题解 二分查找 贪心算法 蓝桥杯 国赛 第1张

一、题目解读

洛谷P10909是一道典型的贪心策略问题,要求在一个递增数列中,通过跳跃到达终点,并允许使用一次“爆发技能”以扩大单次跳跃距离。题目核心在于如何在限定跳跃次数内,合理分配普通跳跃与技能使用,找到最优的最大跳跃距离。

二、解题思路

1. 核心思想:采用二分查找确定最大可行跳跃距离。由于跳跃次数与距离呈反比关系,可通过二分法缩小解的范围。

2. 贪心优化:引入“爆发技能”的两种使用场景——中途遇长距离时使用,或末尾补用(若未使用过)。通过检查函数判断当前距离是否满足条件,并优先利用技能减少总次数。

三、解题步骤

1. 输入处理:读取n(元素数量)、m(最大跳跃次数)及数列a。

2. 特殊情况:n=1时直接输出(a[0]+1)/2,避免二分退化。

3. 二分查找区间:left=1,right=末尾元素值,通过mid=(left+right)/2迭代

4. 检查函数逻辑:

○ 遍历数列,计算相邻距离dist。

○ 若use_boost且未使用技能,且dist>mid但≤2*mid,则触发技能并更新位置。

○ 若dist>mid,按普通规则累加跳跃次数(cnt)。

○ 末尾检查:若技能未用且末尾距离符合条件,补用技能。

5. 二分终止条件:找到满足check(mid, m, false)或check(mid, m, true)的最大mid值。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool check(long long L, const vector<int>& a, int m, bool use_boost) {
    int cnt = 0;
    long long prev = 0;
    bool boost_used = false;
    
    for (int i = 0; i < a.size(); ++i) {
        long long dist = a[i] - prev;
        if (use_boost && !boost_used && dist > L) {
            // 尝试在此处使用爆发技能
            if (dist <= 2 * L) {
                boost_used = true;
                prev = a[i];
                continue;
            }
        }
        
        if (dist > L) {
            cnt += (dist - 1) / L;
            if (cnt > m) return false;
        }
        prev = a[i];
    }
    
    // 如果使用爆发技能但没用上,尝试在最后使用
    if (use_boost && !boost_used) {
        long long last_dist = a.back() - (a.size() > 1 ? a[a.size()-2] : 0);
        if (last_dist > L && last_dist <= 2 * L) {
            boost_used = true;
        }
    }
    
    return cnt <= m && (!use_boost || boost_used);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    
    // 处理特殊情况:n=1时只需要跳一次
    if (n == 1) {
        cout << (a[0] + 1) / 2 << endl;
        return 0;
    }
    
    long long left = 1, right = a.back(), ans = a.back();
    while (left <= right) {
        long long mid = (left + right) / 2;
        if (check(mid, a, m, false) || check(mid, a, m, true)) {
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    
    cout << ans << endl;
    return 0;
}

五、总结

本解法通过二分查找高效定位最优跳跃距离,结合贪心策略灵活处理爆发技能的使用时机,兼顾了时间与空间效率。关键在于将跳跃次数转化为距离约束,并利用技能的双条件检查实现全局优化。该思路适用于类似需要动态平衡资源分配的问题。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣451:ASCII数组计数法 用128个桶解决频率排序问题

力扣451:ASCII数组计数法 用128个桶解决频率排序问题

题目重解给定一个字符串,将字符按照出现频率降序排列。例如输入"tree",可能返回"eetr"或"eert"。题目要求我们不考虑字母顺序,只...

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

一、题目解读2022年蓝桥杯省赛B组机器人塔(洛谷P8785)是一道经典的算法题目,要求处理在一个二维平面上布置的炸雷与排雷火箭。炸雷具有爆炸半径,当排雷火箭引爆后,会触发周围范围内未被引爆的炸雷,形...

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

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

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

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

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

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

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

一、题目解读洛谷2652题要求对一组扑克牌进行排序,目标是找到最少需要调整的次数,使得所有牌形成同花顺。题目中,扑克牌由花色和数字组成,需先按花色排序,再在同花色内按数字排序。核心难点在于如何处理花色...

洛谷P1121题解:动态规划求解环形数组最大子段和问题(附代码注释)

洛谷P1121题解:动态规划求解环形数组最大子段和问题(附代码注释)

一、题目解读洛谷P1121题要求求解环形数组的最大子段和,即在一个环形数组中找到一个连续子段,使其元素和最大。环形数组的特殊性在于首尾元素可相连,需考虑线性子段与跨越首尾的环形子段两种情况。二、解题思...

发表评论

访客

看不清,换一张

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