动态规划
并不是很难,就是情况稍显复杂。
我峨嵋你要分两种情况
1.x为正数
2.x为负数
如果为正数,那么我们直接求出这个数组初始的最大的美丽数然后乘x就可以了。
注意这里的初始最大美丽数最小为0,因为如果全部是负数,那么我们一个也不取
如果为负数,那么很有可能被会出现这样的一种情况
[L,R]为答案区间
[L,ML]初始美丽值为正,[ML,MR]初始美丽值为负,[MR,R]初始美丽值为正
然后我们对[ML,MR]乘x之后得到了最大的美丽值
我们怎么得到这个呢?
首先我峨嵋你可以两个指针O(n^2)的枚举。但是这肯定是不行的。
那么我们动态规划。如何进行动态规划呢?
我们可以分成两段。
第一段[L,MR]第二段[MR,R]
这两段是可以动态规划维护的。转移方程并不难想。
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int max_n = 3e5+100; const ll inf = 1e18; ll a[max_n]; int n;ll x; ll dp[max_n]; ll Solve1(){ for (int i=1;i<=n;++i)dp[i]=max(a[i],dp[i-1]+a[i]); ll ans = 0; for (int i=1;i<=n;++i)ans = max(ans,dp[i]); return ans*x; } ll dp1[max_n],dp2[max_n]; ll Solve2(){ Solve1();ll ans = 0; for (int i=1;i<=n;++i)dp1[i]=max(dp1[i-1],dp[i-1])+x*a[i]; for (int i=n;i>=1;--i)dp2[i]=max(a[i],dp2[i+1]+a[i]); for (int i=1;i<=n;++i)dp2[i]=max(dp2[i],(ll)0); for (int i=1;i<=n;++i)ans = max(ans,max(dp[i],dp2[i+1]+dp1[i])); return ans; } int main(){ scanf("%d %lld",&n,&x); for (int i=1;i<=n;++i)scanf("%lld",&a[i]); if (x>0)printf("%lld\n",Solve1()); else printf("%lld\n",Solve2()); }