codeforces731E Funny Game(DP)
现在主要是以cf上比赛为主了,以后除了我觉得很有必要总结一下的题目,不会每道题都记录在博客上了。这题是一道DP,看起来很像博弈论,但是其中的思想还是有点新颖的。
题意:
给出一系列数,有两个人,每次从这些数的最左边拿走k个数,范围为2~m。特别之处在于,拿走后会把拿走的数的和作为一个新的数放在最左边,要求两个人拿走数之差的最大值。
要点:
看起来很像博弈论,但是其实不是,因为每次拿走后都会将一个等值的数放回,所以我们可以用a[i]数组存储前i个数的和,然后用f表示最大差,现在已经知道如果第一个人将所有数全部拿走的结果是a[n],这样可以写出状态转移方程为ans = max(ans, a[i] - ans),这里解释一下:我们从前找一个点i,那么就是拿a[i],这样下一步的人就会拿到最大差对应的那个分界点,这样两个人的差即为a[i]-f,可以自己用笔算一下就比较清楚了。
#include<iostream>
#include<algorithm>
using namespace std;
long long a[200010];
int main()
{
int n,x;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &x);
a[i] += a[i - 1] + x;
}
long long ans = a[n];
for (int i = n - 1; i>=2; i--)
{
ans = max(ans, a[i] - ans);
}
printf("%I64d\n", ans);
return 0;
}