/*
蒜頭君設計了乙個雙人遊戲,在桌面上放置一排 n 張卡片,第 i 張卡片上有乙個數字 a_i。
兩個人輪流取走一張卡片,直至全部取完。注意每次只能取這一排卡片中的第一張或最後一張。最後取得卡片的數字和最高的玩家獲勝。
蒜頭君和花椰妹開始玩這個遊戲。蒜頭君先手,他可以使用任意策略。花椰妹計算能力有限,
所以她只單純地使用貪心策略,即取兩張卡片中數字較大的一張,如果兩張卡片數字相同,則取第一張。
現在蒜頭君想知道,在最佳策略下,他取得的分數會比花椰妹高多少?
例如 4 張卡片,3 2 10 4。輪流取的卡片為 3, 4 ,10, 2 答案為 (3 + 10) - (4 + 2) = 7
區間dp,用遞迴去轉移更直觀一些
dp(l, r, p) : [l, r]表示剩餘卡牌區間,p表示此時取卡片的玩家,p=0表示蒜頭君,p=1表示花椰妹。
返回值為蒜頭君得分和花椰妹的差值
p = 0 採用最佳策略,需要考慮子局面的分數:dp(l, r, 0) = max(dp(l, r - 1, 1) + a[r], dp(l + 1, r, 1) + a[l]);
p = 1 採用貪心策略,a[l] < a[r], dp(l, r, 1) = dp(l, r - 1, 0) - a[r];
a[l] >= a[r], dp(l, r, 1) = dp(l - 1, r, 0) - a[l];
*/#include
using
namespace std;
const
int maxn =
1005
;int dp[maxn]
[maxn]
;bool vis[maxn]
[maxn]
;//記憶化處理,防止重複計算
int a[maxn]
, n;
intdp
(int l,
int r,
int p)
if(l > r)
vis[l]
[r]=1;
int res =0;
//儲存差值 其實 可以不用宣告此變數 因為dp這個二維陣列 就是存放的區間差值
if(p ==0)
else
return dp[l]
[r]= res;
}int
main()
cout <1, n,0)
<< endl;
//蒜頭君先手權
return0;
}
905 卡片遊戲
時間限制 1000 ms 記憶體限制 65535 kb 難度 1 描述 小明最近宅在家裡無聊,於是他發明了一種有趣的遊戲,遊戲道具是n張疊在一起的卡片,每張卡片上都有乙個數字,數字的範圍是0 9,遊戲規則如下 首先取最上方的卡片放到桌子上,然後每次取最上方的卡片,放到桌子上已有卡片序列的最右邊或者最...
hdu 卡片遊戲
problem description 小明最近宅在家裡無聊,於是他發明了一種有趣的遊戲,遊戲道具是n張疊在一起的卡片,每張卡片上都有乙個數字,數字的範圍是0 9,遊戲規則如下 首先取最上方的卡片放到桌子上,然後每次取最上方的卡片,放到桌子上已有卡片序列的最右邊或者最左邊。當n張卡片全部都放到桌子上...
codevs 卡片遊戲
題目描述 description 桌面上有一疊牌,從第一張牌 即位於頂面的牌 開始從上往下依次編號為1 n.當至少還剩兩張排時進行一下操作 把第一張牌扔掉,然後把新的第一張牌放到整疊牌的最後。輸入n。輸出每次扔掉的牌,以及最後剩下的牌。分析 說是費用流的題目,但是直接用陣列暴力模擬就過了。var t...