结果填空:卡片游戏
- 1000ms
- 131072K
蒜头君设计了一个双人游戏,在桌面上放置一排 nn 张卡片,第 ii 张卡片上有一个数字 a_iai。两个人轮流取走一张卡片,直至全部取完。注意每次只能取这一排卡片中的第一张或最后一张。最后取得卡片的数字和最高的玩家获胜。
蒜头君和花椰妹开始玩这个游戏。蒜头君先手,他可以使用任意策略。花椰妹计算能力有限,所以她只单纯地使用贪心策略,即取两张卡片中数字较大的一张,如果两张卡片数字相同,则取第一张。
现在蒜头君想知道,在最佳策略下,他取得的分数会比花椰妹高多少?
例如 44 张卡片,3 \space 2 \space 10 \space 43 2 10 4。轮流取的卡片为 3, 4 ,10, 23,4,10,2,答案为 (3 + 10) - (4 + 2) = 7(3+10)−(4+2)=7。
现在已知:
n = 100
a = 304 166 849 478 770 991 42 114 85 425 799 91 333 958 401 988 684 709 513 737 672 156 994 575 79 707 282 238 892 479 985 196 996 185 25 766 175 419 231 259 843 30 349 175 987 102 162 23 810 27 111 833 182 104 408 260 162 41 850 54 519 186 601 867 370 625 632 544 395 214 154 238 243 854 764 582 955 278 956 117 304 66 949 485 521 708 96 682 749 945 87 267 482 39 485 851 16 116 746 410
请输出最佳策略下蒜头君得分与花椰妹得分的差值。
样例输入复制
100
304 166 849 478 770 991 42 114 85 425 799 91 333 958 401 988 684 709 513 737 672 156 994 575 79 707 282 238 892 479 985 196 996 185 25 766 175 419 231 259 843 30 349 175 987 102 162 23 810 27 111 833 182 104 408 260 162 41 850 54 519 186 601 867 370 625 632 544 395 214 154 238 243 854 764 582 955 278 956 117 304 66 949 485 521 708 96 682 749 945 87 267 482 39 485 851 16 116 746 410
思路:区间dp
dp[l][r][0] 表示在蒜头君选择当前卡片的情况下,得分差值最大值。
dp[l][r][1]表示在花椰妹选择当前卡片的情况下,得分差值最大值。
l,r表示当前区间是从卡片l到卡片r.
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int dp[N][N][2];
int main()
{
int n;
cin>>n;
int num[100];
for(int i=1; i<=n; i++) cin>>num[i];
for(int len = 0; len < n; len ++)//从最短区间开始遍历
for(int l = 1; l + len <= n; l ++)
{
int r = l + len;
dp[l][r][0] = max(dp[l][r-1][1] + num[r], dp[l+1][r][1] + num[l]);
if(num[l] < num[r]) dp[l][r][1] = dp[l][r-1][0] - num[r];
else dp[l][r][1] = dp[l+1][r][0] - num[l];
}
cout<<dp[1][100][0];
return 0;
}