紙牌博弈 改DP

2021-10-10 05:44:41 字數 1740 閱讀 9564

這個題目刷過一次 沒記住位址

有一串紙牌 只能從紙牌兩邊抽取撲克,有兩名玩家,假設兩名玩家都絕頂聰明會選擇,會選擇最優的情況,抽取的紙牌面值累加為分數,求獲勝者的分數和

輸入:

42 7 100 20

輸出:102

先思考抽牌的情況

從左邊抽 那麼第二個人就從剩下的部分抽

從右邊抽 ------------------------------------------

由於兩個人都是絕頂聰明 ,所以我們要考慮從左右抽取的時候 哪邊更加合適,max(arr[l]+s(arr,l+1,r) , arr[r]+s(arr,l,r-1))

/* 

拿紙牌 3,7,100,20

兩個人只能從左右兩邊拿

返回獲勝者的分數

*/#include

using

namespace std;

// 因為我們只求 開始時先手的人 最高分 所以 當先手f之後是後手 後手肯定只剩最小的情況

// (兩個人都絕頂聰明)

ints

(int arr,

int l,

int r)

;intf(

int arr,

int l,

int r)

ints

(int arr,

int l,

int r)

intmain()

cout<<

f(num ,

1, n)

<

return0;

}

改動態規劃的方法就是加上記憶化,

因為是從乙個區間裡面抽牌 需要表示l到r的最大值

所以用乙個二維陣列儲存dp

dp演算法基本求解步驟:

劃分子問題確定狀態dp[l][r]狀態轉移方程

尋找邊界條件l==r?0:max()

code

int

windp

(vector<

int> arr)

for(

int col=

1; col

return

max(f[0]

[len-1]

,s[0

][len-1]);}

s表依賴自己下和左的值 誰小 誰是

f表依賴自己arr上的和s表中對應的點

註解:上面的圖為f 下面的圖是s

f更新時 依賴arr[ ]和後手s選剩下的值(最小值)

當f選l之後 s返回的是[l+1,r]此區間在s圖中的表示為x點的下面

當f選r之後 s返回的是[l,r-1]此區間在s圖中的表示為x點的左面

s的變化很好理解 選完剩下小的 填進s裡給f用

思路:左程雲

紙牌博弈問題

題目 有乙個整型陣列a,代表數值不同的紙牌排成一條線。玩家a和玩家b依次拿走每張紙牌,規定玩家a先拿,玩家b後拿,但是每個玩家每次只能拿走最左或最右的紙牌,玩家a和玩家b都絕頂聰明,他們總會採用最優策略。請返回最後獲勝者的分數。給定紙牌序列a及序列的大小n,請返回最後分數較高者得分數 相同則返回任意...

紙牌博弈問題

題目 有乙個整型陣列a,代表數值不同的紙牌排成一條線。玩家a和玩家b依次拿走每張紙牌,規定玩家a先拿,玩家b後拿,但是每個玩家每次只能拿走最左或最右的紙牌,玩家a和玩家b都絕頂聰明,他們總會採用最優策略。請返回最後獲勝者的分數。給定紙牌序列a及序列的大小n,請返回最後分數較高者得分數 相同則返回任意...

狀壓 博弈dp

傳送門 題目大意 遊戲的雙方能在 1 n 之間選擇乙個數加到sum上,每個數只能選擇一次。誰先將sum 變得 max 誰就贏了。現在問你,給定 n sum.先手是否能贏 兩方採取最優策略 n 20 max 300 思路 很容易發現n 很小,可以直接狀態壓縮。但是有乙個問題。直觀的想法是開二維陣列,這...