首页 > 编程语言 >【3.5】贪心算法-解优势洗牌(类田忌赛马问题)

【3.5】贪心算法-解优势洗牌(类田忌赛马问题)

时间:2024-09-01 17:22:03浏览次数:12  
标签:std 田忌赛马 最快 3.5 数组 齐王 nums1 田忌 贪心

一、问题

        给定两个 大小相等的数组 A 和 B ,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述。 返回 A 的任意排列,使其相对于 B 的优势最大化。

二、解题思路

        这个问题要求我们重新排列数组A,使得在相同位置上,数组A的元素大于数组B的元素的次数最多,从而最大化数组A相对于数组B的优势。我们可以将数组A视为田忌的马匹,数组B视为齐王的马匹,数组中的数值代表马匹的速度。

        对于任意长度的数组,我们可以采用类似田忌赛马的策略来解决这个问题:

        1. **如果田忌最快的马速度不及齐王最快的马**,那么田忌应该用最慢的马与齐王最快的马比赛。因为齐王最快的马已经超过了田忌最快的马,田忌无论派出哪匹马都会输,所以选择用最慢的马来节省实力。

        2. **如果田忌最快的马速度超过齐王最快的马**,那么田忌应该用最快的马与齐王最快的马比赛。因为田忌最快的马能够赢得这场比赛,所以应该充分利用这匹马的优势。

        这种策略的合理性在于,通过比较田忌和齐王最快的马,我们可以决定是否值得用田忌最快的马去争取胜利。如果田忌最快的马无法胜过齐王最快的马,那么使用最慢的马是明智的选择,因为这样可以保留更强的马匹用于后续的比赛。反之,如果田忌最快的马能够胜过齐王最快的马,那么就应该用它来确保这场比赛的胜利。

        通过这种贪心算法的策略,我们可以在每一步都做出当前最优的选择,从而最大化数组A相对于数组B的优势。

三、代码实现

原理已经了解,我们来看下代码

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

std::vector<int> advantageCount(std::vector<int>& nums1, std::vector<int>& nums2) {
    int length = nums1.size();
    std::vector<int> res(length);
    // 先对数组nums1从小到大进行排序
    std::sort(nums1.begin(), nums1.end());
    // 对数组nums2从大到小排序,这里使用的是优先队列,也就是最大堆,每次出队的都是堆中最大的元素
    // 这里存储的是数组nums2中的元素和元素对应的下标
    std::priority_queue<std::pair<int, int>> pq;
    for (int i = 0; i < length; i++) {
        pq.push({nums2[i], i});
    }
    // 双指针,分别指向数组nums1中的最小值和最大值。可以类比于田忌跑的最慢的马和跑的最快的马
    int left = 0;
    int right = length - 1;
    while (!pq.empty()) {
        // 队列中存放的是数组nums2中的元素,每次出队的都是堆中最大的值,
        // 类比齐王每次都拿出剩下的马中最好的马比赛
        auto cur = pq.top();
        pq.pop();
        int index = cur.second;
        int val = cur.first;
        // 先用nums1中的最大值和nums2中的最大值比较,类似于田忌用最好的马
        // 和齐王最好的马比较,如果田忌最好的马跑的比齐王最好的马跑的快,
        // 就用田忌最好的马和齐王最好的马比赛
        if (nums1[right] > val) {
            res[index] = nums1[right--];
        } else {
            // 如果田忌最好的马没有齐王最好的马跑的快,就用田忌最差的马
            // 和齐王最好的马比赛
            res[index] = nums1[left++];
        }
    }
    return res;
}

int main() {
    std::vector<int> nums1 = {2, 7, 11, 15};
    std::vector<int> nums2 = {1, 10, 4, 11};
    std::vector<int> result = advantageCount(nums1, nums2);
    for (int num : result) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

 

标签:std,田忌赛马,最快,3.5,数组,齐王,nums1,田忌,贪心
From: https://blog.csdn.net/linshantang/article/details/141671914

相关文章

  • 【3.10】贪心算法-找出对应 LCP 矩阵的字符串
    一、题目对任一由n个小写英文字母组成的字符串word,我们可以定义一个nxn的矩阵,并满足:lcp[i][j]等于子字符串 word[i,...,n-1]和word[j,...,n-1]之间的最长公共前缀的长度。给你一个nxn的矩阵lcp。返回与lcp对应的、按字典序最小的字符串 word。如果......
  • “从手动到自动:探索Cursor编辑器和Claude-3.5-Sonnet的AI编程工具“
    Cursor情况简介AI大神AndrejKarpathy都被震惊了!他最近在试用VSCodeCursor+ClaudeSonnet3.5,结果发现这玩意儿比GitHubCopilot还好用!Cursor在短短时间内迅速成为程序员群体的顶流神器,其背后的原因在于其默认使用OpenAI投资的Claude-3.5-Sonnet模型,这一举动不仅改变......
  • 分享丨【题单】贪心算法(基本贪心策略/反悔/区间/字典序/数学/思维/构造)
    作者:灵茶山艾府链接:https://leetcode.cn/circle/discuss/g6KTKL/一、贪心策略有两种基本贪心策略:从最小/最大开始贪心,优先考虑最小/最大的数,从小到大/从大到小贪心。在此基础上,衍生出了反悔贪心。从最左/最右开始贪心,思考第一个数/最后一个数的贪心策略,把n个数的原问题转......
  • Ci522读写器芯片 开锁应用 刷卡功能 电动车NFC一键启动13.56Mhz
    Ci522读写器芯片开锁应用刷卡功能电动车NFC一键启动13.56MhzCI522简介Ci522是工作在13.56MHz频率下的非接触式读写芯片,支持读A卡(CI523支持读A/B卡),可做智能门锁、读手机模拟卡(NFC)开锁等应用。为部分要求低成本,PCB小体积的产品提供了可靠的选择。Ci522与Si522/MFRC522封装不......
  • 【3.4】贪心算法-解按要求补齐数组
    一、问题        给定一个已排序的正整数数组nums,和一个正整数n。从[1,n]区间内选取任意个数字补充到nums中,使得[1,n]区间内的任何数字都可以用nums中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。......
  • Luogu P4425 转盘 题解 [ 黑 ] [ 线段树 ] [ 贪心 ] [ 递归 ]
    转盘:蒟蒻的第一道黑,这题是贪心和线段树递归合并的综合题。贪心破环成链的trick自然不用多说。首先观察题目,很容易发现一个性质:只走一圈的方案一定最优。这个很容易证,因为再绕一圈回来标记前面的和等前面的标记完之后继续走是等价的,并且再绕一圈甚至可能更劣。于是,我们只用走......
  • 代码随想录算法训练营第二十九天(贪心 三)
    力扣题部分:134.加油站题目链接:.-力扣(LeetCode)题面:在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为......
  • 力扣热题100_贪心算法_45_跳跃游戏
    文章目录题目链接解题思路解题代码题目链接45.跳跃游戏II给定一个长度为n的0索引整数数组nums。初始位置为nums[0]。每个元素nums[i]表示从索引i向前跳转的最大长度。换句话说,如果你在nums[i]处,你可以跳转到任意nums[i+j]处:0<=j<=nums[i]......
  • 代码随想录算法day24 | 贪心算法part02 | 122.买卖股票的最佳时机II,55. 跳跃游戏,45.跳
    122.买卖股票的最佳时机II本题解法很巧妙,本题大家可以先自己思考一下然后再看题解,会有惊喜!力扣题目链接(opensnewwindow)给定一个数组,它的第 i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次......
  • 亲测好用,吐血整理 ChatGPT 3.5/4.0 新手使用手册~ 【2024.09 更新】
    废话不多说,直接分享正文~以下是小编为大家搜集到的最新的ChatGPT国内站,各有优缺点。1、AIPlus(稳定使用)推荐指数:⭐⭐⭐⭐⭐     yixiaai.com该网站已经稳定运营了1年多了。2023年3月份第一批上线的网站。网站支持GPT-3.5、4.0及4o、4omini模型,手机和电脑都能用......