题目来源:

https://codeforces.com/contest/1155/problem/D

题意:

给你一个数组和一个数字x,求当前数组最大子串和(可以乘x或者不乘)

思路:(借用大佬的语言描述)

DP[i][3]:
定义乘x的区间叫做"大"区间
dp[i][1]表示,第i个数,未乘x,且在"大"区间之前,所以只能一个状态转移过来,即上一个点也不乘x
dp[i][2]表示,第i个数,乘x,所以可以由两个状态转移过来,即:1、上一个数没乘x,此点为乘x的区间的起点,2、上一个数已经乘过x,
dp[i][3]表示,第i个数不乘x且在“大"区间之后,可以有两个状态转移过来,即1、上一个点为"大"区间的最后一个点,此点为"大"区间结束后的第一个点,2、"大"区间早就结束了。

参考代码:(注意ll)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define ll long long
const int inf = 0x3f3f3f3f;
const int N = 3e5 + 5 ;
using namespace std;
ll a[N];
ll dp[N][5];
int main()
{
    int n,x;
    cin>>n>>x;
    ll ans=0;
    for(int i=1; i<=n; i++)
        cin>>a[i];
    for(int i=1; i<=n; i++)
    {
        dp[i][1]=max(0ll,dp[i-1][1]+a[i]);
        dp[i][2]=max(0ll,max(dp[i-1][1],dp[i-1][2])+a[i]*x);
        dp[i][3]=max(0ll,max(dp[i-1][2],dp[i-1][3])+a[i]);
        for(int j=1; j<=3; j++)ans=max(ans,dp[i][j]);
    }
    cout<<ans<<endl;
    return 0;
}