問題分析:
要求面對n個石子,是否先手必勝
需要知道面對n-1和n-2個石子,是否先手必勝
子問題:
設f[i]表示面對i個石子,是否先手必勝(f[i] = true/false)
f[i] = true , f[i-1] = false and f[i-2] = false ;拿一顆石子或兩顆石子都輸
true , f[i-1] = false and f[i-2] = true ;拿一顆石子輸拿兩顆石子贏
true , f[i-1] = true and f[i-2] = false ;拿一顆石子贏,拿兩顆石子輸
false , f[i-1] = true and f[i-2] = true ;拿一顆石子或兩顆石子都贏
其實就是:對於面對i顆石子的人來說,只要你拿一顆或者兩顆石子對手都贏,則你必輸。故:
f[i] = false if f[i-1] = true and f[i-2] = true else true
初始條件:
f[0] = false,面對0顆石子,先手什麼也不能做,必敗
f[1] = f[2] = true
轉移方程:
f[i] = false if f[i-1] = true and f[i-2] = true else true
計算順序:
f[0]....f[n]
時間複雜度o(n),空間複雜度o(n)
**及注釋如下:
def take_coins(n):
if n == 0:
return false
if n <=2 :
return true
#f[1] = f[2] = true
f = [true for i in range(n+1)]
for i in range(3,n+1):
f[i] = false if f[i-1] == true and f[i-2] == true else true
return f[n]
n = 5
print(take_coins(n))
#結果:true,即必勝
博弈取石子
有一堆石子,a,b兩人輪流從中取出石子,每次取出的石子數目只能為1,3,7或8,最後一枚石子誰取到就是輸方。a,b兩人都足夠聰明,不會做出錯誤的判斷。現給出一定數目的石子,a先取石子,計算a最終是輸是贏,贏用1表示,輸用0表示.輸入描述 第一行為乙個整數n 0 n 100 表示玩n局,接下來n行每行...
dp基礎之博弈型和區間型結合輪流取數字
問題分析 這是一道博弈型dp,其實質上是區間型dp,目標是讓自己拿到的數字和不必對手小 設己方數字和是a,對方是b,目標是a b,等價於a b 0 也就是說,如果兩人都存著自己與對手的數字和之差,sa a b,sb b a,先手目標是讓sa最大化,後手目標讓sb最大化 當一方x面對剩下的數字時,他的...
巴什博弈問題之取石子(博弈)
一天,tt在寢室閒著無聊,和同寢的人玩起了取石子遊戲,而由於條件有限,他 她們是用旺仔小饅頭當作石子。遊戲的規則是這樣的。設有一堆石子,數量為n 1 n 1000000 兩個人輪番取出其中的若干個,每次最多取m個 1 m 1000000 最先把石子取完者勝利。我們知道,tt和他 她的室友都十分的聰明...