题目大意
给一列数,你可以选择一段连续区间(可以为空)将其乘上x,求最大子段和。
解题思路
子段和最大的区间一共有三种情况,要么全是没乘x的,要么全是乘上x的,要么是中间有一段是乘上x两端没乘(两端也可以没有),开个二维数组表示三种状态即可。
代码
const int maxn = 3e5+10;
const int maxm = 2e3+10;
int n;
ll arr[maxn], dp[maxn][3], x;
int main() {
cin >> n >> x;
for (int i = 1; i<=n; ++i) cin >> arr[i];
ll ans = 0;
for (int i = 1; i<=n; ++i) {
dp[i][0] = max(dp[i-1][0]+arr[i], arr[i]);
dp[i][1] = max({dp[i-1][0]+arr[i]*x, dp[i-1][1]+arr[i]*x, arr[i]*x});
dp[i][2] = max({dp[i-1][2]+arr[i], dp[i-1][1]+arr[i], arr[i]});
ans = max({ans, dp[i][0], dp[i][1], dp[i][2]});
}
cout << ans << endl;
return 0;
}