🇨🇳
阿臻的学习笔记
  • 🤖AI
    • 📑README
    • 🕒Scheduling
      • 一种JSSP的DRL环境
    • 📜Paper
      • 神经协同过滤
      • 非侵入信号深度学习
      • 肾透析移植机器学习
      • 心理学随机森林
      • P300数据学习
    • ⚒️Pytorch
      • 1.1数据基础
      • 1.2自动梯度
      • 1.3神经网络
      • 1.4模型实现
      • 2数据操作
    • 🛠️Ray+Gym
    • 📃Graph Neural
      • 图神经网络基础
      • Contrastive Multi-View Representation Learning on Graphs
    • 📽️Deep Learning
      • 《第一章》
      • 《第二章》
      • 《第三章》
      • 《第四章》
      • 台湾陈蕴侬视频2020
    • 🔨MXNet
      • 《第一章》《第二章》
      • 《第三章》
      • 《第四章》
      • 《第五章》
      • 《第六章》
      • 《第七章》
      • 《第八章》
      • 《第九章》
      • 《第十章》
  • 👨‍🏭Study
    • 📔Algorithm
      • Leetcode
        • 第一天(乱刷)
        • 第二天(栈)
        • 第三天(栈)
        • 第四天(堆)(贪心)
        • 第五天(贪心)
        • 第六天(贪心)
        • 第七天(排序)
        • 第八天(排序)
        • 第九天(排序)
        • 第十天(位运算)
        • 第十一天(位运算)
        • 第十二天(位运算)
        • 第十三天(位运算)
        • 第十四天(树)
        • 第十五天(树)
        • 第十六天(树)
        • 第十七天(树)
        • 第十八天(树)
        • 第十九天(树)
        • 第二十天(树)
        • 第二十一天(树)
        • 第二十二天(并查集)
        • 第二十三天(并查集)
        • 第二十四天(DFS)(图)
        • 第二十五天(图)(设计)
        • 第二十六天(拓扑)
        • 第二十七天(字典树)
        • 第二十八天(字典树)
        • 第二十九天(树状数组)(二叉搜索树)
        • 第三十天(递归)
        • 第三十一天(脑筋急转弯)
        • 第三十二天(脑筋急转弯)
        • 第三十三天(记忆化)
        • 第三十四天(队列)
        • 第三十五天(队列)
        • 第三十六天(极小化极大)
        • 第三十七天(几何)
        • 第三十八天(蓄水池抽样)
        • 第三十九天(数组)
        • 第四十天(数组)
        • 第四十一天(数组)
        • 第四十二天(数组)
        • 第四十三天(数组)
        • 第四十四天(数组)
        • 第四十五天(数组)
        • 第四十六天(数组)
      • Sort
        • 最小堆
        • 归并排序(merge_sort)
    • 📓Knowledge
      • python补码
    • 🔧Other
      • pythonic语法
      • Ubuntu备忘
由 GitBook 提供支持
在本页

这有帮助吗?

导出为 PDF
  1. Study
  2. Algorithm
  3. Leetcode

第三十六天(极小化极大)

今天完成题目:866,486,375 866:石子游戏

  • 转换思想,有一个总分,自己先手则最大化,敌人先手则最小化

  • 最终判断总分是否大于0,若是,则说明自己先手胜利

  • 此题答案恒为True,因为(先手可以选择所有的奇数堆或者偶数堆,对手只能选择和你相反的选择)

    • 显然,亚历克斯总是赢得 2 堆时的游戏。 通过一些努力,我们可以获知她总是赢得 4 堆时的游戏。

    • 如果亚历克斯最初获得第一堆,她总是可以拿第三堆。 如果她最初取到第四堆,她总是可以取第二堆。第一 + 第三,第二 + 第四 中的至少一组是更大的,所以她总能获胜。

    • 我们可以将这个想法扩展到 N 堆的情况下。设第一、第三、第五、第七桩是白色的,第二、第四、第六、第八桩是黑色的。 亚历克斯总是可以拿到所有白色桩或所有黑色桩,其中一种颜色具有的石头数量必定大于另一种颜色的。

# 高阶函数
from functools import lru_cache
class Solution:
    def stoneGame(self, piles):
        N = len(piles)
        # last recently unused,缓存,None表示无限制
        @lru_cache(None)
        def dp(i, j):
            # The value of the game [piles[i], piles[i+1], ..., piles[j]].
            if i > j: return 0
            parity = (j - i) % 2 # 判断是否是亚历克斯(先手)
            if parity == 1:  # first player
                return max(piles[i] + dp(i+1,j), piles[j] + dp(i,j-1)) # 越大,越能获胜
            else:
                return min(-piles[i] + dp(i+1,j), -piles[j] + dp(i,j-1)) # 越小,越能减少对手获得的分数

        return dp(0, N - 1) > 0

486:预测赢家

  • 类似866,但是起始的数量不一定是偶数

  • 可以使用866的方法,略加修改即可

375:猜数字大小 二

  • 遍历所有的1-n中的i,可以获得所有的耗费,选择最小的耗费

  • cost(1,n)=i+max(cost(1,i−1),cost(i+1,n))

  • 方法有两种:

    • 方法一,利用lru_cache和函数递归

    • 方法二,利用dp数组(也是cost数组)

# 方法一
from functools import lru_cache
class Solution:
    def getMoneyAmount(self, n: int) -> int:
        # dp = [0,0,1,3,4,6,8,10]
        
        @lru_cache(None)
        def dp(i,j):
            '''
                dp(i,j):从i-j所需要的最少能保证赢的钱数
            '''
            if i>=j:
                return 0
            else:
                num = 0xffffffff
                for x in range(i,j+1): # 假设猜了x
                    temp = max(dp(i,x-1),dp(x+1,j))+x # 左右两边中更花钱的可能(为了保证赢)
                    if num>temp: # 选择更少的(为了用最少的花费保证能赢)
                        num = temp
                return num
        return dp(1,n)
上一页第三十五天(队列)下一页第三十七天(几何)

最后更新于3年前

这有帮助吗?

👨‍🏭
📔