题目描述

爱丽丝和鲍勃继续他们的石子游戏。许多堆石子 排成一行,每堆都有正整数颗石子 piles[i]。游戏以谁手中的石子最多来决出胜负。

爱丽丝和鲍勃轮流进行,爱丽丝先开始。最初,M = 1。

在每个玩家的回合中,该玩家可以拿走剩下的 前 X 堆的所有石子,其中 1 <= X <= 2M。然后,令 M = max(M, X)。

游戏一直持续到所有石子都被拿走。

假设爱丽丝和鲍勃都发挥出最佳水平,返回爱丽丝可以得到的最大数量的石头。

示例 1:

输入:piles = [2,7,9,4,4]
输出:10
解释:如果一开始Alice取了一堆,Bob取了两堆,然后Alice再取两堆。爱丽丝可以得到2 + 4 + 4 = 10堆。如果Alice一开始拿走了两堆,那么Bob可以拿走剩下的三堆。在这种情况下,Alice得到2 + 7 = 9堆。返回10,因为它更大。

示例 2:

输入:piles = [1,2,3,4,5,100]
输出:104

提示:

  • 1 <= piles.length <= 100
  • 1 <= piles[i] <= 104

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/stone-game-ii

题目分析

应该是搜索问题。对每一种取石子的方式进行模拟,返回当前策略下双方的石子数量。为了保证爱丽丝和鲍勃都发挥出最佳水平,每一次取石子的方式都要保证为当前最优方式。

判断最优方式的策略:(参考@灵茶山艾府的题解)

  • 如果当前可以把剩下的石子都拿完,则全部拿取为最优策略
  • 如果不能把剩下的石子一次性拿完,因为剩下的石子总数固定,如果对手能拿的石子最少,则为自己当前的最优选择

因此需要计算每一步时剩下的石子数,采用后缀和的方式实现。
初步实现代码如下:

class Solution {public:int optimum_choice(int cur,int m, vector<int>& remain){if(cur+2*m>=remain.size()){return remain[cur]; //如果能把剩下的都拿完}int op_min=remain[0];for(int i=1;i<=2*m;i++){op_min = min(op_min,optimum_choice(cur+i,max(m,i),remain)); //计算出当前玩家拿i-cur堆时,对手可能拿到的最少石子数//cout<<i<<" "<<op_min<<endl;}return remain[cur]-op_min; //当前剩下的总数减去对手拿的石子数为自己拿到的数量}int stoneGameII(vector<int>& piles) {int m=1;int size = piles.size();vector<int> remain(size); //后缀和,记录剩下的石子数remain[size-1] = piles[size-1];for(int i=size-2;i>=0;i--){remain[i] = remain[i+1] + piles[i];//cout<<i<<" "<<remain[i]<<endl;}return optimum_choice(0,m,remain);}
};

通过样例但是超时,继续优化:
采用记忆化搜索减少搜索次数,从而减少运行时间。当剩下的堆数和m相同时,最优策略总是相同的。使用mem数组标记该方案是否计算过

class Solution {public:int optimum_choice(int cur,int m, vector<int>& remain, int* mem){if(cur+2*m>=remain.size()){return remain[cur]; //如果能把剩下的都拿完}if(mem[(cur)*remain.size()+m]!=0){return mem[cur*remain.size()+m];}int op_min=remain[0];for(int i=1;i<=2*m;i++){op_min = min(op_min,optimum_choice(cur+i,max(m,i),remain,mem)); //计算出当前玩家拿i-cur堆时,对手可能拿到的最少石子数}mem[(cur)*remain.size()+m]=remain[cur]-op_min; //当前剩下的总数减去对手拿的石子数为自己拿到的数量return mem[(cur)*remain.size()+m];}int stoneGameII(vector<int>& piles) {int m=1;int size = piles.size();vector<int> remain(size); //后缀和,记录剩下的石子数int mem[size][size];    //第一维记录指针,第二维记录Mmemset(mem,0,sizeof(mem));remain[size-1] = piles[size-1];for(int i=size-2;i>=0;i--){remain[i] = remain[i+1] + piles[i];//cout<<i<<" "<<remain[i]<<endl;}return optimum_choice(0,m,remain,*mem);}
};

总结

经过三天的练习,大概认清了自己目前的水平。遇到问题时能正确的判断出应该使用什么算法,但是具体策略的制定不清晰,以及在具体落实到代码上的过程中会出现逻辑上的错误,包括指针越界等。希望通过大量的练习可以改善以上问题。

LeetCode 1140.石子游戏 II相关推荐

  1. LeetCode 1140. 石子游戏 II(DP)*

    文章目录 1. 题目 2. 解题 1. 题目 亚历克斯和李继续他们的石子游戏.许多堆石子 排成一行,每堆都有正整数颗石子 piles[i].游戏以谁手中的石子最多来决出胜负. 亚历克斯和李轮流进行,亚 ...

  2. LeetCode 1690. 石子游戏 VII(博弈DP)

    文章目录 1. 题目 2. 解题 1. 题目 石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 . 有 n 块石子排成一排.每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的石头,并获 ...

  3. LeetCode 1686. 石子游戏 VI(贪心)

    文章目录 1. 题目 2. 解题 283 / 1660,前17% 681 / 6572,前10.4% 1. 题目 Alice 和 Bob 轮流玩一个游戏,Alice 先手. 一堆石子里总共有 n 个石 ...

  4. LeetCode 1406. 石子游戏 III(DP)

    1. 题目 Alice 和 Bob 用几堆石子在做游戏.几堆石子排成一行,每堆石子都对应一个得分,由数组 stoneValue 给出. Alice 和 Bob 轮流取石子,Alice 总是先开始.在每 ...

  5. Leetcode 45. 跳跃游戏 II

    Leetcode 45. 跳跃游戏 II 题目 给你一个非负整数数组 nums ,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组 ...

  6. leetcode 45. 跳跃游戏 II 46. 全排列

    leetcode 45. 跳跃游戏 II 46. 全排列 45. 跳跃游戏 II 难度中等1273收藏分享切换为英文接收动态反馈 给你一个非负整数数组 nums ,你最初位于数组的第一个位置. 数组中 ...

  7. leetcode 45.跳跃游戏 II

    一.题意 给出一个非负整数数组 nums ,数组中的每个元素代表在该位置可以跳跃的最大长度.使用最少的跳跃次数到达数组的最后一个位置.假设总是可以到达数组的最后一个位置. 二.解法 贪心算法. 解法一 ...

  8. 1056-取石子游戏II

    取石子游戏II 描述 一堆石子有n个,两人轮流取.每次取最少取1个,最多取m个.取完者胜.先取者负输出"Second win".先取者胜输出"First win" ...

  9. LeetCode 1690.石子游戏VII

    LeetCode 1690.石子游戏VII 问题描述: 石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 . 有 n 块石子排成一排.每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的 ...

最新文章

  1. html超链接到index,HTML基础___超链接 第四天
  2. 非托管资源在虚拟机中的管理
  3. python2基础教程廖雪峰云-Python 基础教程
  4. 可可肉的奋斗(第一天)2012-12-24
  5. Alpha版使用说明
  6. php实现附件上传下载,PHP实现文件上传与下载
  7. sketchup生成面域插件_独家教程 | 快速抓取“高精准”场地信息,康石石教你生成不同“体量”地形...
  8. 计算机语言恢复,win10系统找回消失不见语言栏的恢复方法
  9. Qt:Windows编程—Qt实现本地服务管理
  10. SPOJ DQUERY 求区间内不同数的个数 主席树
  11. LNMP一键自动安装脚本
  12. 软件开发UI设计流程
  13. iOS 强制屏幕实现旋转功能
  14. Exception in thread “main“ redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication
  15. 边云协同的优点_探析云边协同的九大应用场景
  16. 蓝桥杯陶陶摘苹果C语言,Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
  17. php 防注册机,discuz论坛自动注册机 伪造注册会员数
  18. 【读书笔记】【More Effective C++】异常(Exceptions)
  19. pyecharts主题theme风格推荐
  20. MySQLdb的安装与使用

热门文章

  1. android drawable 比例,Drawable适配的那些事,仔仔细细研究下。
  2. 每一个JavaScript开发者都应该知道的10道面试题
  3. 树莓派系列二(语音识别)
  4. Deno加入ECMA
  5. Python基础学习3——列表
  6. STM32F103ZET6时钟
  7. 第3章 Groovy初学者
  8. LeetCode-Python-52. N皇后 II
  9. JAVAWeb的学习笔记
  10. VCS视频学习中的一个例子代码:dff.v和dff_tb.v