栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【数据结构与算法】之深入解析“石子游戏VI”的求解思路与算法示例

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【数据结构与算法】之深入解析“石子游戏VI”的求解思路与算法示例

一、题目要求
  • Alice 和 Bob 轮流玩一个游戏,Alice 先手,一堆石子里总共有 n 个石子,轮到某个玩家时,他可以移出一个石子并得到这个石子的价值。Alice 和 Bob 对石子价值有不一样的的评判标准,双方都知道对方的评判标准。
  • 给你两个长度为 n 的整数数组 alicevalues 和 bobValues,alicevalues[i] 和 bobValues[i] 分别表示 Alice 和 Bob 认为第 i 个石子的价值。
  • 所有石子都被取完后,得分较高的人为胜者,如果两个玩家得分相同,那么为平局,两位玩家都会采用 最优策略 进行游戏。
  • 请你推断游戏的结果,用如下的方式表示:
    • 如果 Alice 赢,返回 1;
    • 如果 Bob 赢,返回 -1;
    • 如果游戏平局,返回 0。
  • 示例 1:
输入:alicevalues = [1,3], bobValues = [2,1]
输出:1
解释:
如果 Alice 拿石子 1 (下标从 0开始),那么 Alice 可以得到 3 分。
Bob 只能选择石子 0 ,得到 2 分。
Alice 获胜。
  • 示例 2:
输入:alicevalues = [1,2], bobValues = [3,1]
输出:0
解释:
Alice 拿石子 0 , Bob 拿石子 1 ,他们得分都为 1 分。
打平。
  • 示例 3:
输入:alicevalues = [2,4,3], bobValues = [1,6,7]
输出:-1
解释:
不管 Alice 怎么操作,Bob 都可以得到比 Alice 更高的得分。
比方说,Alice 拿石子 1 ,Bob 拿石子 2 , Alice 拿石子 0 ,Alice 会得到 6 分而 Bob 得分为 7 分。
Bob 会获胜。
二、求解算法 ① 贪心算法
  • 假设只有两个石头,对于 a, b 的价值分别是 a1,a2,b1,b2:
    • 第一种方案是 A 取第一个,B 取第二个,A 与 B 的价值差是 c1 = a1 - b2;
    • 第二种方案是 A 取第二个,B 取第一个,A 与 B 的价值差是 c2 = a2 - b1;
  • 那么这两种方案对于 A 来说哪一种更优,就取决于两个方案的价值差的比较。
  • 记 c = c1 - c2 = (a1 - b2) - (a2 - b1) = (a1 + b1) - (a2 + b2),如果 c > 0 那么方案一更优,如果 c == 0,那么两种方案价值一样,如果 c < 0 ,那么方案二更优。
  • 比较两个方案的优劣就如同比较 a1 + b1 与 a2 + b2 的优劣,归纳一下就是比较每个下标 i 的 a[i] + b[i] 的优劣,所以贪心的策略:将两组石头的价值合并,每次取价值最大的那一组。
  • 合并 alicevalues 与 bobValues 的数组,按最大价值从大到小排列,Alice 先选,Bob 后选,偶数下标就标称 Alice 选取的石头的总价值,Bob 选的则是奇数下标的石子,比较两个总和。
  • C++ 示例:
class Solution {
public:
    int stoneGameVI(vector& alicevalues, vector& bobValues) {
		vector> mp; // 记录价值和以及下标
		int n = alicevalues.size();
		for(int i = 0; i < n; i++) {
			int dis = alicevalues[i] + bobValues[i];
			mp.emplace_back(dis, i);
		}
		sort(mp.rbegin(), mp.rend()); // 从大到小排序
		int sum1 = 0, sum2 = 0;
		for(int i = 0; i < n; i++) {
			if(i % 2 == 0) sum1 += alicevalues[mp[i].second];// 偶数下标a来取
			else sum2 += bobValues[mp[i].second];  		  	 // 奇数下标b来取
		}
		if(sum1 == sum2) return 0; // 比较结果
		else if(sum1 > sum2) return 1;
		else return -1;
    }
};
② 数学推理
  • 双赢才是赢,不仅 Alice 要认为某块石头的价值大,Bob 也要认为的时候,才是真的大。
  • 因此,将某块石头在 Alice 眼中的价值 +Bob 眼里的价值相加,排序,然后 Alice 和 Bob 依次进行挑选,最比较 Alice 和 Bob 的得分。
  • C++ 示例:
class Solution {
public:
    int stoneGameVI(vector& alicevalues, vector& bobValues) {
        vector>vc;
        int len=alicevalues.size();
        for(int i=0;iB?1:-1;
    }
};
三、博客之星
  • 今年是我第一次参加博客之星,需要各位大佬的支持,麻烦百忙之中,抽出一点宝贵的时间,给我投一下票:https://bbs.csdn.net/topics/603955258 给我一个五星(列表会一一全部回复),不胜感激!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/690605.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号