123. 连续子数组最大和(卡码网周赛第十九期(23年小红书提前批笔试真题))
题目描述
小红拿到了一个数组,她希望进行最多一次操作:将一个元素修改为x。小红想知道,最终的连续子数组最大和最大是多少?
输入
第一行输入一个正整数t,代表询问次数。
对于每次询问,输入两行:
第一行输入两个正整数n和x。代表数组的大小,以及小红可以修改成的元素。 第二行输入n个正整数a_i,代表小红拿到的数组
输出
输出 t 行,每行输出一个整数,代表连续子数组的最大和。
样例输入
3
5 10
5 -1 -5 -3 2
2 -3
-5 -2
6 10
4 -2 -11 -1 4 -1
样例输出
15
-2
15
提示
例如输入:
6 10
4 -2 -11 -1 4 -1
可以用10 替换 -11,连续子数组的最大和:4 -2 10 -1 4,总和为:15
数据范围:
1 ≤ t ≤ 100000
1 ≤ n ≤ 200000
-10^9 ≤ x ,a_i ≤ 10^9
每组所有询问的n的和不超过200000。
题解1(C++版本)
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
LL dp[N][2]; //也可以将第一维去掉,因为状态转移只跟前一个状态相关
// dp[i][0]表示以第i个元素结尾,且到第i个元素(包括i)为止,没有修改元素,得到的子数组和的最大值
// dp[i][1]表示以第i个元素结尾,且到第i个元素(包括i)为止,修改某个元素,得到的子数组和的最大值
LL Max(LL A, LL B){
return A > B ? A : B;
}
int t,n,x,a[N];
int main(){
scanf("%d", &t);
while(t--){
memset(dp, 0, sizeof dp);
memset(a, 0, sizeof a);
scanf("%d%d", &n, &x);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
LL ans = -1e15;
for(int i = 1; i <= n; i++){
dp[i][0] = (dp[i - 1][0] > 0 ? dp[i - 1][0] : 0) + a[i];
dp[i][1] = Max((dp[i - 1][0] > 0 ? dp[i - 1][0] : 0) + x, dp[i - 1][1] + a[i]);
ans = Max(ans, Max(dp[i][0], dp[i][1]));
}
printf("%lld\n", ans);
}
return 0;
}
标签:卡码,周赛,10,LL,元素,123,输入,数组,dp
From: https://blog.csdn.net/qq_45332149/article/details/139348559