2018QBXT刷题游记(26)
【2018QBXT刷题游记】
Day8 TEST9
T2 game
【问题描述】
小 N 和小 A 在玩这样的一个游戏:给定初始数列 Q,小 N 先把某个前缀
(可以为空) 的数字全部乘上 -A,小 A 再把某个后缀 (可以为空) 的数字全部乘上 -B,小 N 想让最后所有数的和尽量大,小 A 想让最后所有数的和尽量的小。
小 A 绝对不会失误,所以小 N 想找到某个方法使得最后所有数的和尽量大,请帮助小 N 求出最大的值是多少吧。
【分析】记前缀和为 Si,设小 N 取前 K 个数,小 A 取第 p 个数之后
的所有数,分相交和不相交,最终总和为:
当对于任意一个k,两式中的项和是不变的,
所以项的大小直接影响整个式子的值。
观察到,式1中项为正,所以小A希望越小越好,
同理,式2中越大越好。
所以只需要预处理出,
注意细节处理:如哪里是0-n,哪里是1-n
哦对,ans的绝对值需要非常非常大……别问我怎么知道的
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 1000007
#define ll long long
ll sum[MAXN],l[MAXN],r[MAXN],ans,tmp;
int n,a,b;
int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
ans=-99999999999999999;
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++){
scanf("%lld",&tmp);
sum[i]=sum[i-1]+tmp;
l[i]=max(l[i-1],sum[i]);
}
r[n]=sum[n];
for(int i=n-1;i!=-1;i--)r[i]=min(r[i+1],sum[i]);
for(int i=0;i<=n;i++){
ans=max(ans,min((1+b)*r[i]-(a+1)*sum[i]-b*sum[n],b*(a+1)*sum[i]-a*(b+1)*l[i]-b*sum[n]));
}
printf("%lld\n",ans);
return 0;
}
qwqwqwq