Coins in a Line I & 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?

Example

n = 1, return true.

n = 2, return true.

n = 3, return false.

n = 4, return true.

n = 5, return true.

分析:

既然可以拿1个和2个,那么只要coin的个数能够被3整除,那么第一个拿的百分百会输掉。

 1 public class Solution {
 2     /**
 3      * @param n: an integer
 4      * @return: a boolean which equals to true if the first player will win
 5      */
 6     public boolean firstWillWin(int n) {
 7         // write your code here
 8         if (n % 3 == 0) return false;
 9         return true;
10     }
11 }

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.

分析:

来自:http://www.cnblogs.com/theskulls/p/4963317.html

定义dp[i]表示从i到end能取到的最大值。 当我们在i处,有两种选择:

1.若取values[i],对方可以取values[i+1] 或者values[i+1] + values[i+2]。

当对方取values[i+1] 后 ,我们只能从 i+2 到end内取,我们所取得最大值是dp[i+2],  注意:对方所选取的结果一定是使得我们以后选取的值最小

当对方取values[i+1] + values[i+2]后,我们只能从i+3到end内取,我们所取得最大值是dp[i+3]。

此时:dp[i] = values[i] + min(dp[i+2],dp[i+3]) , 注意:对方所选取的结果一定是使得我们以后选取的值最小

2.若取values[i] + values[i+1],对方可取values[i+2] 或者values[i+2] + values[i+3]

当对方取values[i+2]后,我们只能从i+3到end内取,我们取得最大值是dp[i+3]

当对方取values[i+2]+values[i+3]后,我们只能从i+4到end内去,我们取得最大值是dp[i+4]

此时:dp[i] = values[i] + values[i+1]+min(dp[i+3],dp[i+4])

这里的取最小值和上面一样的意思,对方选取过之后的值一定是使得我们选取的值最小,对方不傻并且还很聪明

最后我们可以取上面两个dp[i]的最大值,就是答案,这里意思是:对方留得差的方案中,我们选取的最大值。

 1 public class Solution {
 2 
 3     public boolean firstWillWin(int[] values) {
 4         // write your code here
 5         // dp 表示从i到end 的最大值
 6         // int values[] ={1,2,4,3,4,8,5,6,12};
 7         int len = values.length;
 8         // 长度小于2的时候第一个人一定获胜
 9         if (len <= 2) return true;
10         int dp[] = new int[len + 1];
11         dp[len] = 0;
12         dp[len - 1] = values[len - 1];
13         dp[len - 2] = values[len - 1] + values[len - 2];
14         dp[len - 3] = values[len - 3] + values[len - 2];
15         for (int i = len - 4; i >= 0; i--) {
16             dp[i] = values[i] + Math.min(dp[i + 2], dp[i + 3]);
17             dp[i] = Math.max(dp[i], values[i] + values[i + 1] + Math.min(dp[i + 3], dp[i + 4]));
18 
19         }
20         int sum = 0;
21         for (int a : values)
22             sum += a;
23         return dp[0] > sum - dp[0];
24     }
25 }

 

posted @ 2016-07-10 04:06  北叶青藤  阅读(200)  评论(0编辑  收藏  举报