877. Stone Game and 486. Predict the Winner

49 篇文章 0 订阅
1 篇文章 0 订阅

Typical game theory question.

In dp solution, their solution is the same. However before introducing the dp solution, we have a look at the greedy solution of Stone Game.

Greedy solution of Stone Game

If piles' index started with 1, we label all the odd indices black and even indices white. The first player can either choose all white or all black, thus when you know the sum of black and white, as the first player you can always win the game, when the length of the piles is even number.

DP solution:

  1. dp[left][right] = the interval from left to right, the difference of scores of two player
  2. both players are smart always choose the best one the maximize the difference
  3. we update the state from smallest interval to the biggest interval, the correctness got guaranteed, as we found all the combination and keep the smallest one, to get the at least answer. "at least" means in the worst situation the first player would higher or lower than the second player
  4. About transfer, [left, left + 1, left + 2.......right - 2, right - 1, right], just a simple simulation, if you choose nums[left] than you inheriate the state of dp[left + 1][right], other wise dp[left][right - 1], just a simulation of the original game, dont dig too much here, that's meaningless, in dp we just needed to solve the edge case and consider the smallest problem, pass the answer to bigger problem.
    So, we have, dp[i][j] = max(nums[left] - dp[left + 1][right], nums[right] - dp[left][right - 1])
    since the state represent the "difference", dp[left + 1][right] and dp[left][right - 1] are opponents turn, you need to deduct this to get how many scores you are heading over or loss behind.

Code:

Stone Game

class Solution {
public:
    bool stoneGame(vector<int>& piles) {
        int dp[510][510];
        for(int i = 0; i < piles.size(); i++)dp[i][i] = piles[i];
        for(int len = 2; len <= piles.size(); len++){
            for(int i = 0; i < piles.size() - len; i++){
                int j = i + len - 1;
                dp[i][j] = max(piles[i] - dp[i + 1][j], piles[j] - dp[i][j - 1]);
            }
        }
        return dp[0][piles.size() - 1] >= 0;
    }
};

Predict the winner:

class Solution {
public:
    bool PredictTheWinner(vector<int>& nums) {
        int dp[26][26], n = nums.size();
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; i++)dp[i][i] = nums[i];
        for(int len = 2; len <= n; len++){
            for(int lft = 0; lft <= n - len; lft++){
                int rght = lft + len - 1;
                dp[lft][rght] = max(nums[lft] - dp[lft + 1][rght], nums[rght] - dp[lft][rght - 1]);
            }
        }
        return dp[0][n - 1] >= 0;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值