日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

排成一条线的纸牌博弈问题

發布時間:2025/4/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 排成一条线的纸牌博弈问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目】

  給定一個整型數組arr,代表數值不同的紙牌排成一條線。玩家A和玩家B依次拿走每張紙牌,規定玩家A先拿,玩家B后拿,但是每個玩家每次只能拿走最左邊或者最右邊的一張牌,最后所拿牌累加和最大的玩家獲勝,玩家A和玩家B都絕頂聰明。請返回最后獲勝者的分數。

【舉例】

  arr = [1, 2, 100, 4]?
  玩家A先拿1,玩家B拿4,玩家A再拿100,玩家B再拿2,游戲結束,玩家A獲勝,分數為101。

【基本思路】

  首先分析暴力遞歸的方法。定義遞歸函數f(i, j)表示如果arr[i…j]這個排列上的紙牌被絕頂聰明的人先拿,最終會獲得什么分數。定義遞歸函數s(i, j),表示如果arr[i…j]這個排列上的紙牌被絕頂聰明的人后拿,最終能獲得什么分數。

首先分析f(i, j),具體過程如下:

如果i == j,表示此時只有一張牌,當然會被先拿牌的人拿走,所以返回arr[i]即可。

如果i != j,那么此時有兩種選擇,一種是先拿arr[i],一種是先拿arr[j]。如果先拿走arr[i],那么對于剩下的arr[i+1…j],玩家成了后拿牌的人,所以他能獲得的分數為arr[i] + s(i+1, j);同理如果先拿arr[j],那么他能獲得的分數為arr[j] + s(i, j-1)。因為玩家是決定聰明的人,所以他會選擇兩個決策中最優的,即max(arr[i] + s(i+1, j), arr[j] + s(i, j-1))。

接下來分析s(i, j),具體過程如下:

如果i == j,表明此時只有一張牌,對于后拿牌的人來說,他肯定拿不上,說以返回 0。

如果i != j,那么此時玩家的拿牌方式其實受到對手的影響,如果對手選擇的是arr[i]那么給玩家留下的就是arr[i+1…j],對于排列arr[i+1…j]玩家成了先拿牌的人,所以他能得到的分數為f(i+1, j)。同理,如果對手選擇的是arr[j]那么給玩家留下的就是arr[i…j-1],對于排列arr[i…j-1]玩家成了先拿牌的人,所以他能得到的分數為f(i, j-1)。因為對手也是絕頂聰明的,所以留給玩家的一定是最壞的情況,所以玩家只能選擇兩個決策中最差的,即max(f(i+1, j), f(i, j-1))
?

def win1(L):"""暴力遞歸"""if L == None or len(L) == 0:return 0return max(f(L,0,len(L)-1),s(L,0,len(L)-1))def f(L,i,j):if i==j:return L[i]return max(L[i]+f(L,i+1,j),L[j] + f(L,i,j-1))def s(L,i,j):if i==j:return 0return min(f(L,i+1,j),f(L,i,j+1))def win2(L):if L == None or len(L) == 0:return 0f = [[0]*len(L)] * len(L)s = [[0]*len(L)] * len(L)for j in range(1,len(L)):f[j][j] = L[j]for i in range(j-1,0,-1):f[i][j] = max(L[i]+s[i+1][j],L[j]+s[i][j-1])s[i][j] = min(f[i+1][j],f[i][j-1])return max(f[0][len(L)-1],s[0][len(L)-1])

?

總結

以上是生活随笔為你收集整理的排成一条线的纸牌博弈问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。