蘑菇真的贵,友情价更高
Description
由于提莫为巡逻准备的蘑菇太多了,多余的蘑菇路上种不下,于是他精心挑选了一些蘑菇拜访他的好朋友小炮
提莫的蘑菇一共有n个,对于编号为i的蘑菇魔力值是ai。蘑菇的魔力值越高,小炮就越喜欢。当然因为二人是好朋友,蘑菇魔力值最低也不会小于0
提莫要与小炮分享这些蘑菇,他们制定了一个因吹斯听的分配规则:
两人按1-n的顺序逐个分配每个蘑菇的归属权
对于一个蘑菇,如果这一轮的分配者将这个蘑菇分给自己,那么下一轮分配权将转让给对方
反之,如果分配者将蘑菇分配给对方,下一轮他还将持有分配权
你可能会以为提莫会让着小炮,不你想多了!爱恶作剧的提莫会尽力让小炮所获得的蘑菇的魔力值的总和尽可能小!(友尽警告
请你帮小炮算算,如果小炮先手分配,他所能获得的蘑菇的魔力值之和的最大值会是多少?
注意:提莫和小炮都足够聪明且均采取最优策略
Input
单组输入
第一行输入一个n,代表物品的数量,1 <= n <= 3e5
第二行输入n个数字a1-an,代表这n个蘑菇的魔力值,0 <= ai <= 1e9
Output
一个数字,小炮所能获得的蘑菇的魔力值之和的最大值。
Sample Input 1
2
10 20
Sample Output 1
20
Hint
对于样例1,小炮可以要走第一个蘑菇,提莫拿走第二个蘑菇,小炮的喜爱程度是10
小炮也可以把第一个蘑菇给提莫,继续持有第二个蘑菇的分配权,然后拿走第二个蘑菇喜爱程度是20
所以小炮能拿到蘑菇的最大喜爱程度是20
Source
2019年集训队选拔赛
这个题目,我不会,别人教我的,这个只能从后面往前面推,至于为什么,我也不知道,好像是从前面往后面会有后效性,你可以试试3 3 2 1 从前往后推就不对,从后往前就对了
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 100;
ll sum[maxn], dp[maxn],dp1[maxn],a[maxn]; int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lld", &a[i]);
}
for (int i = n; i >= 1; i--)
{
sum[i] = sum[i+1] + a[i];
}
for (int i = n; i >= 1; i--)
{
dp[i] = max(dp[i + 1], dp1[i + 1]+a[i]);
dp1[i] = sum[i] - dp[i];
}
printf("%lld\n", dp[1]);
return 0;
}