這個題目刷過一次 沒記住位址
有一串紙牌 只能從紙牌兩邊抽取撲克,有兩名玩家,假設兩名玩家都絕頂聰明會選擇,會選擇最優的情況,抽取的紙牌面值累加為分數,求獲勝者的分數和。
輸入:
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;
}
改動態規劃的方法就是加上記憶化,dp演算法基本求解步驟:因為是從乙個區間裡面抽牌 需要表示l到r的最大值
所以用乙個二維陣列儲存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 很小,可以直接狀態壓縮。但是有乙個問題。直觀的想法是開二維陣列,這...