題目翻譯
給你一個長度為 \(N\) 的整數序列, \(A=(A_1,A_2,…,A_N)\) ,和一個整數 \(C\) 。
在執行以下操作最多一次後,找出A中元素的最大可能和:
選擇兩個整數 \(l\) 和 \(r\) ( \(1≤l≤r≤N\) ),
將 \(A_l,A_{l+1},…,A_r\) 分別乘以 \(C\) 。
演算法
法一(暴力)
可以 \(O_{(N^2)}\) 暴力列舉 \(l\) 和 \(r\) 。
法二(正解)
前置知識:最大子段和。
參考該題思路,我們可以求出最大子段和,來最大化 \(C\) 乘上的區間和
程式碼如下:
#include<bits/stdc++.h>
#define int long long
#define fd(i,a,b) for(int i=a;i<=b;i=-~i)
using namespace std;
int n,c,a[300100],f[300100],sum[300100],maxx=-1e6,ans=0;
signed main()
{
ios::sync_with_stdio(0);
cin>>n>>c;
fd(i,1,n) cin>>a[i],sum[i]=sum[i-1]+a[i],maxx=max(a[i],maxx);
//字首和
if(c>0&&maxx<0)//全負且c>0
{
cout<<sum[n];
return 0;
}
if(c<=0)
{
fd(i,1,n) a[i]=-a[i];//將C<=0的情況轉化為c>0的情況
}
fd(i,1,n)
{
if(i==1) f[i]=a[i];
else f[i]=max(a[i],f[i-1]+a[i]);
ans=max(ans,f[i]);
}
if(c>0) cout<<sum[n]+ans*(c-1);
else cout<<sum[n]+ans*(1-c);
//這裡減一是因為sum[n]已經加過一次了
return 0;
}
無關的話(稽核大大,求過審):被禁言了,怎麼解啊?
感謝觀看!