题意:
给出一个序列$a[n]$和数字$x$,你可以选择任意一个区间把区间中的每个数乘上$x$。
问区间和的最大值是多少。
思路:
$dp[i][0]$表示第i位在更新区间的前面,$dp[i][1]$表示在更新区间中,$dp[i][2]$表示在更新区间的后面。转移为:
$dp[i][0]=max(0,dp[i-1][0]+a[i])$
$dp[i][1]=max(dp[i][0],dp[i-1][1]+a[i]*x)$
$dp[i][2]=max(dp[i][1],dp[i-1][2]+a[i])$
取$max$
代码:
1 //#include<bits/stdc++.h> 2 #include <set> 3 #include <map> 4 #include <stack> 5 #include <cmath> 6 #include <queue> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 14 #define ll long long 15 #define pll pair<ll,ll> 16 #define pii pair<int,int> 17 #define bug printf("********* ") 18 #define FIN freopen("input.txt","r",stdin); 19 #define FON freopen("output.txt","w+",stdout); 20 #define IO ios::sync_with_stdio(false),cin.tie(0) 21 #define ls root<<1 22 #define rs root<<1|1 23 #define pb push_back 24 25 using namespace std; 26 const int inf = 2e9 + 7; 27 const ll Inf = 1e18 + 7; 28 const int maxn = 3e5 + 5; 29 const int mod = 1e9 + 7; 30 31 ll dp[maxn][5], ans = 0; 32 33 int main() 34 { 35 ll n, x, a; 36 scanf("%lld %lld", &n, &x); 37 for (ll i = 1; i <= n; ++i) 38 { 39 scanf("%lld", &a); 40 dp[i][0] = max(0LL, dp[i - 1][0] + a); 41 dp[i][1] = max(dp[i][0], dp[i - 1][1] + a * x); 42 dp[i][2] = max(dp[i][1], dp[i - 1][2] + a); 43 ans = max(ans, dp[i][2]); 44 } 45 printf("%lld ", ans); 46 }