中文english
有n
個不同價值的硬幣排成一條線。兩個參賽者輪流從 左邊 依次拿走 1 或 2 個硬幣,直到沒有硬幣為止。計算兩個人分別拿到的硬幣總價值,價值高的人獲勝。
請判定 先手玩家 必勝還是必敗?
若必勝, 返回true
, 否則返回false
.
樣例 1:
輸入: [1, 2, 2]
輸出: true
解釋: 先手玩家直接拿走兩顆硬幣即可.
樣例 2:
輸入: [1, 2, 4]
輸出: false
解釋: 無論先手拿乙個還是兩個, 後手可以拿完, 然後總價值更高.
輸入測試資料 (每行乙個引數)如何理解測試資料?
解法一:動態規劃
dp[i]代表的是倒數n-i個,逆著算,例如dp[length - 2] = values[length - 2] + values[length - 1] ,表示的是i到length - 1可以拿到的最大值
classsolution:
"""@param values: a vector of integers
@return: a boolean which equals to
true
ifthe first player will win
"""def firstwillwin(self, values):
# write your code here
#動態規劃
#如果是len(values)
<=3的情況,則直接給出答案
#如果是len(valeus) >3的情況,分情況,要麼先手拿乙個,要麼拿兩個
length =len(values)
if (length <= 2): return
true
dp = [0
for _ in range(length + 1
)] total = 0
#如果是
<=3的話
#如果是只拿最後乙個的話,先手必拿
dp[length - 1] = values[length - 1
] #如果是剩餘最後兩個的話,先手也必拿
dp[length - 2] = values[length - 1] + values[length - 2
] #如果是剩餘三個的話,那麼先手最優策略是拿前兩個,最後乙個留給後手
dp[length - 3] = values[length - 2] + values[length - 3
]
total = sum(values[length - 3
:]) #如果是大於3的話,分情況考慮
for i in range(length - 4, -1, -1
): total +=values[i]
#先手要麼拿乙個,要麼拿兩個,後手也是最優策略,所以後手也盡可能的多拿,min(dp[i + 2], dp[i + 3
]) dp[i] = max(values[i] + min(dp[i + 2], dp[i + 3]), values[i] + values[i + 1] + min(dp[i + 3], dp[i + 4
]))
#最後比較兩者大小,肯定是先手拿,也就是第乙個
return dp[0] > total - dp[0
]
中文english
有n
個硬幣排成一條線。兩個參賽者輪流從右邊依次拿走 1 或 2 個硬幣,直到沒有硬幣為止。拿到最後一枚硬幣的人獲勝。
請判定 先手玩家 必勝還是必敗?
若必勝, 返回true
, 否則返回false
.
樣例 1:
輸入: 1
輸出: true
樣例 2:
輸入: 4
輸出: true
解釋:
先手玩家第一輪拿走乙個硬幣, 此時還剩三個.
這時無論後手玩家拿乙個還是兩個, 下一次先手玩家都可以把剩下的硬幣拿完.
o(1) 時間複雜度且o(1) 儲存。
輸入測試資料 (每行乙個引數)如何理解測試資料?
解法:動態規劃
classsolution:
"""@param n: an integer
@return: a boolean which equals to
true
ifthe first player will win
"""def firstwillwin(self, n):
# write your code here
#當前必勝和必敗由前面兩個決定
#只考慮先手,and表示的是後手的最優策略,只要有前面先手有乙個為false,那麼後手一定是true
#dp[i] = dp[i - 2] and dp[i - 3] or dp[i - 3] and dp[i - 4
] #當前先手 =取乙個後手的最優策略 取兩個後手的最優策略(所以中間是and,表示,只要之前先手乙個為false,此時後手採取最優策略,一定為true)
if not n: return
false
if n <= 2: return
true
dp = [false for _ in range(n + 1
)] #前面三個的話,是固定
dp[1] =true
dp[2] =true
dp[3] =false
for i in range(4, n + 1
): dp[i] = (dp[i - 2] and dp[i - 3]) or (dp[i - 3] and dp[i - 4
])
return
dp[n]
硬幣排成線
題目 有 n 個硬幣排成一條線。兩個參賽者輪流從右邊依次拿走 1 或 2 個硬幣,直到沒有硬幣為止。拿到最後一枚硬幣的人獲勝。請判定 先手玩家 必勝還是必敗?若必勝,返回 true,否則返回 false.樣例樣例 1 輸入 1 輸出 true 樣例 2 輸入 4 輸出 true 解釋 先手玩家第一輪...
lintcode 硬幣排成線
有 n 個硬幣排成一條線。兩個參賽者輪流從右邊依次拿走 1 或 2 個硬幣,直到沒有硬幣為止。拿到最後一枚硬幣的人獲勝。請判定 先手玩家 必勝還是必敗?若必勝,返回 true,否則返回 false.輸入 4 輸出 true 解釋 先手玩家第一輪拿走乙個硬幣,此時還剩三個.這時無論後手玩家拿乙個還是兩...
lintcode 硬幣排成線2
有 n 個不同價值的硬幣排成一條線。兩個參賽者輪流從 左邊 依次拿走 1 或 2 個硬幣,直到沒有硬幣為止。計算兩個人分別拿到的硬幣總價值,價值高的人獲勝。請判定 先手玩家 必勝還是必敗?若必勝,返回 true,否則返回 false.樣例 1 輸入 1,2,2 輸出 true 解釋 先手玩家直接拿走...