[ARC174A] A Multiply 题解 Solution

分别考虑 c c c 的正负性:

  • c c c 为正数,我们肯定是想把最大子段和乘上 c c c,可以让总和最大。

证明:

设最大子段和为 m a x n maxn maxn,数组总和为 s u m sum sum,目前答案为 $ sum-maxn+maxn\times c=sum+maxn\times(c-1)$。

假设再加入一个数 p p p 更优,则答案为 s u m − m a x n − p + ( m a x n + p ) × c = s u m + ( m a x n + p ) × ( c − 1 ) sum-maxn-p+(maxn+p)\times c=sum+(maxn+p)\times (c-1) summaxnp+(maxn+p)×c=sum+(maxn+p)×(c1)

因为我们假设加入 p p p 更优,所以

s u m + m a x n × ( c − 1 ) < s u m + ( m a x n + p ) × ( c − 1 ) sum+maxn\times(c-1)<sum+(maxn+p)\times (c-1) sum+maxn×(c1)<sum+(maxn+p)×(c1)

化简后,得 m a x n < m a x n + p maxn<maxn+p maxn<maxn+p,但是 m a x n maxn maxn 是最大子段和,与结论相悖。

所以把最大子段和乘上 c c c 最优。

  • c c c 为负数,我们肯定是想把最小子段和乘上 c c c,可以让总和最大,证明方法如上。

至此,我们可以开始编码代码了,求解最大 / / / 最小字段和类比最大字段和,但是还要注意两个细节:

  1. 可能不进行操作更优;
  2. 记得开 l o n g l o n g long long longlong

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define N 300010
int maxn=-1e16,ans,suma,sumb,minn=1e16,c,sum;
signed main(){
	int n;
	cin>>n>>c;
	for(int i=1,x;i<=n;i++){
		cin>>x,suma=max(suma+x,x),sumb=min(sumb+x,x),sum+=x;
		maxn=max(maxn,suma),minn=min(minn,sumb);
	}
	cout<<max(sum,max(maxn*c+sum-maxn,minn*c+sum-minn));
	return 0;
}

完结撒花(作者的第一篇题解)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值