首页 > 其他分享 >1140. 石子游戏 II

1140. 石子游戏 II

时间:2023-04-08 18:14:16浏览次数:49  
标签:1140 piles idx int 复杂度 石子 dfs II

题目链接:1140. 石子游戏 II

方法一:dfs(超时)

解题思路

  • 题目要求\(Alice\)取得的石子数尽可能的多,那么就要使得\(Bob\)取得的石子尽可能的少,但是\(Bob\)也想要取得更多的石子,因此\(Alice\)在每次选取时,要使得在此种选取方法下,\(Bob\)能取的石子数最小。
  • 现定义\(dfs(idx, m)\)表示从\(piles[idx]\)开始拿,\(M = m\)时,能够取得的最大石子数量;初始化\(piles\)数组为后缀和数组\(s\),\(s[i] = \sum_{j=i}^{n-1}piles[j]\)。
  • 由于从当前\(idx\)开始取,石子的总和为\(s[idx]\),\(那么当前能取得的最大值 = s[idx] - 当前操作之后能取得的最大值中的最小值\),即\(dfs(idx, m) = s[idx] - min_{x=1}^{2m}dfs(idx+x, max(m, x))\)。
  • \(结果为dfs(0, 1)\)。

代码

class Solution {
public:
    int stoneGameII(vector<int>& piles) {
        int n = piles.size();
        for (int i = n - 2; i >= 0; i -- ) piles[i] += piles[i + 1];
        function<int(int, int)> dfs = [&](int idx, int m) -> int { // function类模板 + lambda表达式
            if (idx + 2 * m >= n) return piles[idx]; // 若可以一次拿走剩余所有石堆,则返回剩余所有石子数量
            int mi = INT_MAX;
            for (int x = 1; x <= 2 * m; x ++ ) mi = min(mi, dfs(idx + x, max(x, m)));
            return piles[idx] - mi;
        };
        return dfs(0, 1);
    }
};

方法二:记忆化搜索优化dfs

解题思路

由于在递归的过程中会多次求相同的\(dfs(i, m)\)的值,那么为了使得每一种\(dfs(i, m)\)只求一次,那么可以使用数组\(f[i][m]\)存取相应的值,再次遇到时直接取值返回即可。

代码

class Solution {
public:
    int stoneGameII(vector<int>& piles) {
        int n = piles.size();
        for (int i = n - 2; i >= 0; i -- ) piles[i] += piles[i + 1];
        int f[n][(n + 1) / 4 + 1];
        memset(f, -1, sizeof(f));
        function<int(int, int)> dfs = [&](int idx, int m) -> int { // function类模板 + lambda表达式
            if (idx + 2 * m >= n) return piles[idx]; // 若可以一次拿走剩余所有石堆,则返回剩余所有石子数量
            int &res = f[idx][m];
            if (res != -1) return res;
            int mi = INT_MAX;
            for (int x = 1; x <= 2 * m; x ++ ) mi = min(mi, dfs(idx + x, max(x, m)));
            res = piles[idx] - mi;
            return res;
        };
        return dfs(0, 1);
    }
};

复杂度分析

时间复杂度:\(O(n^3)\),单个状态的计算时间为\(O(n)\),状态个数为\(O(n^2)\);
空间复杂度:\(O(n^2)\)。

方法三:dp

解题思路

舍去递归中“递”的过程—向下,直接从“归”—向上着手。

代码

class Solution {
public:
    int stoneGameII(vector<int> &piles) {
        int s = 0, n = piles.size(), f[n][n + 1];
        for (int i = n - 1; i >= 0; --i) {
            s += piles[i];
            for (int m = 1; m <= i / 2 + 1; ++m) { 
                // 当选取到i时,m可能取得值的范围。每次x可以取的值都为1,或则为2m,两种极端情况下m的范围。
                if (i + m * 2 >= n) f[i][m] = s;
                else {
                    int mn = INT_MAX;
                    for (int x = 1; x <= m * 2; ++x)
                        mn = min(mn, f[i + x][max(m, x)]);
                    f[i][m] = s - mn;
                }
            }
        }
        return f[0][1];
    }
};

复杂度分析

同方法二

详情参考灵茶-教你一步步思考动态规划!

标签:1140,piles,idx,int,复杂度,石子,dfs,II
From: https://www.cnblogs.com/lxycoding/p/17298928.html

相关文章

  • 26. 删除有序数组中的重复项 & 80. 删除有序数组中的重复项 II
    力扣题目链接(26)给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重......
  • 力扣-877-石子游戏
    我尝试使用昨天猫鼠游戏的思路来解决这个博弈问题,也就是DFSprivate: intalice,bob;//用来分别计数两人手上的石子数量public: booldfs(vector<int>&piles,intstart,intend,boolfirstTurn){ //用两个指针来标记剩余石子堆的起始/结束位置 //出口条件是:石子选......
  • IIS 配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler
    https://www.cnblogs.com/skylaugh/p/6376426.html我运行在iis中配置的那个网站后,报错:错误代码0x800700b7配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler”节 这个问题原因在于window7的IIS默认用的是ASP.NETv4.0应用程序池。解决方法:把这......
  • 113. 路径总和ii
    给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。说明:叶子节点是指没有子节点的节点。示例:给定如下二叉树,以及目标和sum=22classSolution{private:voiddfs_find(TreeNode*cur,intsum,inttargetSum,vector<int>&path,v......
  • Windows 短文件名相关 - IIS短文件名泄露
    今天接网安通告,说服务器有IIS短文件名泄露。可这短文件名是什么?拿完通告后回来一通查了个遍终于看明白了。先说短文件名是什么资料传说很久很久以前windows的文件名不能超过8个文件名和3个扩展名,也就是12345678.123就是最大长度了。但是到了windows95的时候,这个长度被扩展到......
  • IIC总线协议—读写EEPROM
    1、I2C简介I2C通讯协议(Inter-IntegratedCircuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。2、I2C物理层I2C总线只需要两条总线线路,一条双向串行数据线(SDA),一......
  • 合并石子
    #include<iostream>#include<string.h>usingnamespacestd;constintN=310;intn;ints[N];intf[N][N];intmain(){scanf("%d",&n);memset(f,0x3f,sizeoff);for(inti=1;i<=n;i++){intx;......
  • day 38 62.不同路径 | 63. 不同路径 II | 343. 整数拆分
    一个机器人位于一个mxn网格的左上角(起始点在下图中标记为“Start”)。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径? 输入:m=3,n=7输出:28想要求dp[i][j],只能有两个方向来推导出来,即d......
  • HDU - 3081 Marriage Match II(二分图最大匹配 + 并查集)
    题目大意:有n个男生n个女生,现在要求将所有的男女配对,所有的男女都配对的话,算该轮游戏结束了。接着另一轮游戏开始,还是男女配对,但是配对的男女不能是之前配对过的。问这游戏能玩多少轮男女能配对的条件如下1.男女未曾吵架过。2.如果两个女的是朋友,那么另一个女的男朋友可以和......
  • asciinema 方便的终端录屏方案
    asciinema方便的终端录屏方案,我们可以直接使用cli工具就可以方便的进行终端录制了,然后可以自己提供一份website基于官方提供的asciinema-player进行播放参考玩法  简单说明:我们可以基于s3以及asciinema提供的工具自己包装一个ui当然也可以直接使用官方提供的asci......