随手练——博弈论入门 leetcode - 486. Predict the Winner

题目链接:https://leetcode.com/problems/predict-the-winner/

1.暴力递归

当前数组左边界:i,右边界:j;

对于先发者来说,他能取到的最大值是:max(arr[i] + second(arr, i + 1, j), arr[j] + second(arr, i, j - 1));

(arr[i] + 作为后发者,在 i+1 到 j 上取得的值),(arr[j] + 作为后发者,在 i 到 j-1 上取得的值) 中大的一个。

对于后发者来说,他是被动的,他只能得到 先发者选剩下的,相对较差的那个,min(first(arr, i + 1, j), first(arr, i, j - 1));

(作为先发者,在 i+1 到 j 上取得的值),(作为先发者,在 i 到 j-1 上取得的值)中小的一个。

class Solution {
public:
    int first(vector<int>&arr,int i,int j) {
        if (i == j)return arr[i];
        return max(arr[i] + second(arr, i + 1, j), arr[j] + second(arr, i, j - 1));
    }
    int second(vector<int>&arr, int i, int j) {
        if (i == j)return 0;
        return min(first(arr, i + 1, j), first(arr, i, j - 1));
    }
    bool PredictTheWinner(vector<int>& arr) {
        int f = first(arr, 0, arr.size() - 1);
        //这个s用arr数组的sum减出来 效率更高.
        int s = second(arr, 0, arr.size() - 1);
        if (f >= s)return true;
        return false;
    }
};

2.改进暴力递归

将后发者的函数,嵌套在形参中。

第一个如果也是用求出数组的sum来减的话,两个效率应该是没什么区别的。

class Solution {
public:
    int first(vector<int>&arr, int i, int j) {
        if (i == j)return arr[i];
        if (i + 1 == j)return max(arr[i], arr[j]);

        return max(
            arr[i] + min(first(arr, i + 2, j), first(arr, i + 1, j - 1)),
            arr[j] + min(first(arr, i, j - 2), first(arr, i + 1, j - 1)));
    }
    bool PredictTheWinner(vector<int>& nums) {
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
        }
        int f = first(nums, 0, nums.size() - 1);
        if (sum - f <= f)return true;
        return false;
    }
};

3.动态规划

我们可以根据递归(第一个递归)的写法,改成DP,两个表都是只用得到 斜上三角部分。

先发者的表对角线是arr[i],i = j 只有一个元素,后发者的对角线是0。

观察递归  

以图中为例,这个first[i][j]和second[i][j]依赖的都是橙色的四个的值。

class Solution {
public:
    int f[21][21] = { 0 };
    int s[21][21] = { 0 };
    bool PredictTheWinner(vector<int>& arr) {
        for (int j = 0; j < arr.size(); j++){
            f[j][j] = arr[j];
            for (int i = j - 1; i >= 0; i--) {
                f[i][j] = max(arr[i] + s[i + 1][j], arr[j] + s[i][j - 1]);
                s[i][j] = min(f[i + 1][j], f[i][j - 1]);
            }
        }
        return f[0][arr.size() - 1] >= s[0][arr.size() - 1];
    }
};

第二个递归也是可以改成动态规划的,只用一个first数组。不过需要初始化除了对角线,还有 first[i][i+1] (0 ≤ i < arr.length)置的值。

原文地址:https://www.cnblogs.com/caozicheng1999/p/11701247.html

时间: 2024-10-02 13:05:11

随手练——博弈论入门 leetcode - 486. Predict the Winner的相关文章

LN : leetcode 486 Predict the Winner

lc 486 Predict the Winner 486 Predict the Winner Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a

LC 486. Predict the Winner

Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the

[Leetcode] DP-- 486. Predict the Winner

Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the

486. Predict the Winner

Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the

博弈论入门题 kiki&#39;s game

Problem Description Recently kiki has nothing to do. While she is bored, an idea appears in his mind, she just playes the checkerboard game.The size of the chesserboard is n*m.First of all, a coin is placed in the top right corner(1,m). Each time one

POJ - 2348 Euclid&#39;s Game(博弈论入门题)

题目链接:poj.org/problem?id=2348 题意:给出两个数,两个人进行博弈,每个人都采取最优策略. 每个人可以进行操作:两个数中较大数减去较小数的倍数(可以是1,2...X倍),使得其中一个数先为零的获胜. 每次都先把较小值给a,较大值给b.一开始把必胜态给先手的那个人,然后进行判断. 1.b-a<=a  没办法只能一次一次计算,必胜态不断变换,直到其中一个数刚好为0. 2.b-a>a   不管怎样都是必胜态.b - xa <= a如果这个是必败态,那么b - (x-1)

随手练——数独 HDU - 5547 坑!坑!坑!

题目链接:HDU-5547 http://acm.hdu.edu.cn/showproblem.php?pid=5547 解题思想:随手练-- 数独 POJ - 2676 (回溯法+DFS) HDU 的这题实在是太坑了,M 数组开成 int 就过不了,改成 char 就过了.对着别人AC的代码,一点点试,到最后才试出来,数组的问题,但是不能理解啊,什么鬼,这也错?? 然后发现题目描述里有一句:Each test case starts with an empty line followed by

博弈论入门

博弈论入门 博弈 巴什博弈 Bash Game 模型 只有一堆n个物品,两个人从轮流中取出(1~m)个:最后取光者胜. 思路 考虑到 若n=m+1 那么 第一个人不论如何取都不能取胜. 进一步我们发现 若 n=k*(m+1)+r; 先取者拿走 r 个,那么后者再拿(1~m)个 n=(k-1)*(m+1)+s: 先取者再拿走s 个 最后总能造成 剩下n=m+1 的局面. 因此,此时先手有必赢策略.相对应的,若n=k*(m+1) 那么先取者必输. 因此我们就可以写出对应程序(n,m>0) int B

[LeetCode] Predict the Winner 预测赢家

Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the