zoukankan      html  css  js  c++  java
  • [LintCode] Coins in a Line II Review

    There are n coins with different value in a line. Two players take turns to take one or two coins from left side until there are no more coins left. The player who take the coins with the most value wins.

    Could you please decide the first player will win or lose?

    Example

    Given values array A = [1,2,2], return true.

    Given A = [1,2,4], return false.

    Solution 1. Recursion 

    In order for the first player to win, the coin value he gets must be bigger than a half of the total value of n coins. 

    For a given start index that the first player can pick one or two coins at,  he can either pick one coin of values[startIdx] or two coins of values[startIdx] + values[startIdx + 1].  

    Given that the second player plays optimally too, we have the following optimal substructure.

    As we can see from the optimal substructure, there exists many overlapping subproblems that are redundantly recomputed, making this recursive solution inefficient.

    26         int pickOneVal = Math.min(fPMaxValue(values, startIdx + 2, currVal), 
    27                          fPMaxValue(values, startIdx + 3, currVal)) + values[startIdx];
    28         int pickTwoVal = Math.min(fPMaxValue(values, startIdx + 3, currVal),
    29                          fPMaxValue(values, startIdx + 4, currVal)) + values[startIdx] + values[startIdx + 1];
    30         return Math.max(pickOneVal, pickTwoVal);

     1 public class Solution {
     2     public boolean firstWillWin(int[] values) {
     3         if(values == null || values.length == 0){
     4             return false;
     5         }
     6         if(values.length <= 2){
     7             return true;
     8         }
     9         int sum = 0; 
    10         for(int i = 0; i < values.length; i++){
    11             sum += values[i];
    12         }
    13         return fPMaxValue(values, 0, 0) > sum / 2;
    14     }
    15     private int fPMaxValue(int[] values, int startIdx, int currVal){
    16         int diff = values.length - startIdx;
    17         if(diff == 2 || diff == 3){
    18             return currVal + values[startIdx] + values[startIdx + 1];
    19         }
    20         if(diff == 1){
    21             return currVal + values[startIdx];
    22         }
    23         if(diff <= 0){
    24             return currVal;
    25         }
    26         int pickOneVal = Math.min(fPMaxValue(values, startIdx + 2, currVal), 
    27                          fPMaxValue(values, startIdx + 3, currVal)) + values[startIdx];
    28         int pickTwoVal = Math.min(fPMaxValue(values, startIdx + 3, currVal),
    29                          fPMaxValue(values, startIdx + 4, currVal)) + values[startIdx] + values[startIdx + 1];
    30         return Math.max(pickOneVal, pickTwoVal);
    31     }
    32 }

    Solution 2. Dynamic Programming 

    Since solution 1 has both optimal substructure and overlapping subproblems, we can apply dynamic programming to avoid redundant recomputation of subproblems.

    Dp state: dp[i] is the most value player one can get when there is i coins left.

    Dp function: 

    dp[i] = Math.max(Math.min(dp[i - 2], dp[i - 3]) + values[n - i],  Math.min(dp[i - 3], dp[i - 4]) + values[n - i] + values[n - i + 1]);

     1 public class Solution {
     2     public boolean firstWillWin(int[] values) {
     3         if(values == null || values.length == 0){
     4             return false;
     5         }
     6         if(values.length <= 2){
     7             return true;
     8         }
     9         int sum = 0; 
    10         for(int i = 0; i < values.length; i++){
    11             sum += values[i];
    12         }
    13         int n = values.length;
    14         int[] dp = new int[n + 1];
    15         dp[0] = 0;
    16         dp[1] = values[n - 1];
    17         dp[2] = values[n - 2] + values[n - 1];
    18         dp[3] = values[n - 3] + values[n - 2];
    19         for(int i = 4; i <= n; i++){
    20             dp[i] = Math.max(Math.min(dp[i - 2], dp[i - 3]) + values[n - i], 
    21                              Math.min(dp[i - 3], dp[i - 4]) + values[n - i] + values[n - i + 1]);
    22         }
    23         return dp[n] > sum / 2;
    24     }
    25 }
  • 相关阅读:
    微信公共服务平台开发(.Net 的实现)5-------解决access_token过期的问题
    微信公共服务平台开发(.Net 的实现)4-------语音识别
    微信公共服务平台开发(.Net 的实现)3-------发送文本消息
    微信公共服务平台开发(.Net 的实现)2-------获得ACCESSTOKEN
    微信公共服务平台开发(.Net 的实现)1-------认证“成为开发者”
    checkboxlist 横向显示,自动换行
    VMware Workstation unrecoverable error: (vmx)虚拟机挂起后无法启动问题
    ASP.NET给DataGrid,Repeater等添加全选批量删除等功能
    redis 优缺点 使用场景
    redis消息队列
  • 原文地址:https://www.cnblogs.com/lz87/p/6936075.html
Copyright © 2011-2022 走看看