[LintCode] Coins in a Line II

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 }
时间: 2024-11-11 03:10:30

[LintCode] Coins in a Line II的相关文章

[LintCode] Coins in a Line III

Coins in a Line III There are n coins in a line. Two players take turns to take a coin from one of the ends of the line until there are no more coins left. The player with the larger amount of money wins. Could you please decide the first player will

[LintCode] Coins in a Line 一条线上的硬币

There are n coins in a line. Two players take turns to take one or two coins from right side until there are no more coins left. The player who take the last coin wins. Could you please decide the first play will win or lose? Have you met this questi

Coins in a Line II

ref: http://www.lintcode.com/en/problem/coins-in-a-line-ii/# 有个博客说的挺好的,比九章自己写的清楚 http://www.cnblogs.com/theskulls/p/4963317.html 意思是这样的: 如果我们在第i个位置,那么我们有两种选择,我们要选取里面更大的 1. 我们只拿一个values[i],那么对方也是很机智的,他会试图给我们最差的结果,会选择拿一个[i+1]或者两个[i+1]&[i+2],试图给我们留更小的值,

LintCode &quot;Coins in a Line&quot;

Recursion + Memorized Search(DP). And apparently, the code below can be iterative with only 3 vars - DP. class Solution { unordered_map<int, bool> cache; public: bool go(int n) { if (n <=0) return false; if (n < 3) return true; if(cache.find(n

Coins in a Line I &amp; II

Coins in a Line I There are n coins in a line. Two players take turns to take one or two coins from right side until there are no more coins left. The player who take the last coin wins. Could you please decide the first play will win or lose? Exampl

[LeetCode] 877. Stone Game == [LintCode] 396. Coins in a Line 3_hard tag: 区间Dynamic Programming, 博弈

Alex and Lee play a game with piles of stones.  There are an even number of piles arranged in a row, and each pile has a positive integer number of stones piles[i]. The objective of the game is to end with the most stones.  The total number of stones

Coins in a Line

ref: http://www.lintcode.com/en/problem/coins-in-a-line/ There are n coins in a line. Two players take turns to take one or two coins from right side until there are no more coins left. The player who take the last coin wins. Could you please decide

LeetCode Coins in a Line

There are n coins in a line. Two players take turns to take one or two coins from right side until there are no more coins left. The player who take the last coin wins. Could you please decide the first play will win or lose? 该题类似于下题: 箱子里面有一百个球,甲和乙分别

Coins in a Line III

There are n coins in a line. Two players take turns to take a coin from one of the ends of the line until there are no more coins left. The player with the larger amount of money wins. Could you please decide the first player will win or lose? Given