codeforces Round 63-div2-D.Beautiful Array(线性动归)

原题地址

D. Beautiful Array

You are given an array aa consisting of nn integers. Beauty of array is the maximum sum of some consecutive subarray of this array (this subarray may be empty). For example, the beauty of the array [10, -5, 10, -4, 1] is 15, and the beauty of the array [-3, -5, -1] is 0.

You may choose at most one consecutive subarray of aa and multiply all values contained in this subarray by xx. You want to maximize the beauty of array after applying at most one such operation.

Input

The first line contains two integers nn and xx (1≤n≤3⋅105,−100≤x≤1001≤n≤3⋅105,−100≤x≤100) — the length of array aa and the integer xx respectively.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (−109≤ai≤109−109≤ai≤109) — the array aa.

Output

Print one integer — the maximum possible beauty of array aa after multiplying all values belonging to some consecutive subarray xx.

Examples

input

Copy

5 -2
-3 8 -2 1 -6

output

Copy

22

input

Copy

12 -3
1 3 3 7 1 3 3 7 1 3 3 7

output

Copy

42

input

Copy

5 10
-1 -2 -3 -4 -5

output

Copy

0

Note

In the first test case we need to multiply the subarray [-2, 1, -6], and the array becomes [-3, 8, 4, -2, 12] with beauty 22([-3, 8, 4, -2, 12]).

In the second test case we don‘t need to multiply any subarray at all.

In the third test case no matter which subarray we multiply, the beauty of array will be equal to 0.

对于每一个数,都有3种状态:

0:当前这个数不*x,且前面的数都没*x

1:当前这个数*x,

2:当前这个数不*x,且前面的数有*x

设dp[i][j]为前i个数在第i个数为j状态选取时能取得的最大值。

那么不难得出,

dp[i][0]依赖于dp[i-1][0],f[i][1]依赖于dp[i-1][0],dp[i-1][1],f[i][2]依赖于dp[i-1][1],dp[i-1][2]。

因为可以舍去前一部分最大值为负数的数列不要,只取一段字串,所以每一个状态还可以依赖于0。

那么动归方程为:

dp[i][0]=max(0ll,dp[i-1][0])+a[i];
dp[i][1]=max(0ll,max(dp[i-1][0],dp[i-1][1]))+a[i]*x;
dp[i][2]=max(0ll,max(dp[i-1][1],dp[i-1][2]))+a[i];

比较每个i的每一个状态,取其最大值,就时最终答案。

#include <iostream>
#include <stdio.h>
using namespace std;
int n,x;
long long a[300010];
long long dp[300010][5];

int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n>>x;
    for(int i=1;i<=n;i++) cin>>a[i];
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        dp[i][0]=max(0ll,dp[i-1][0])+a[i];
        dp[i][1]=max(0ll,max(dp[i-1][0],dp[i-1][1]))+a[i]*x;
        dp[i][2]=max(0ll,max(dp[i-1][1],dp[i-1][2]))+a[i];
        ans=max(ans,max(dp[i][0],max(dp[i][1],dp[i][2])));
    }
    cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/BakaCirno/p/10758491.html

时间: 2024-11-06 17:00:08

codeforces Round 63-div2-D.Beautiful Array(线性动归)的相关文章

codeforces Round #250 (div2)

a题,就不说了吧 b题,直接从大到小排序1-limit的所有数的lowbit,再从大到小贪心组成sum就行了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #define N 200000 6 using namespace std; 7 int pos[N],a[N],s[N],f[N],la[N],b[N],i,j,k,ans,n,p

codeforces round #257 div2 C、D

本来应该认真做这场的,思路都是正确的. C题,是先该横切完或竖切完,无法满足刀数要求,再考虑横切+竖切(竖切+横切), 因为横切+竖切(或竖切+横切)会对切割的东西产生交叉份数,从而最小的部分不会尽可能的大. 代码如下,虽然比较长.比较乱,但完全可以压缩到几行,因为几乎是4小块重复的代码,自己也懒得压缩 注意一点,比如要判断最小块的时候,比如9行要分成2份,最小的剩下那份不是9取模2,而应该是4 m/(k+1)<=m-m/(k+1)*k          #include<bits/stdc+

Codeforces Round#320 Div2 解题报告

Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Finding Team Member codeforces 579C A Problem about Polyline codeforces 579D "Or" Game codeforces 579E Weakness and Poorness codeforces 579F LCS Aga

Codeforces Round #254(div2)A

很有趣的题.想到了就非常简单,想不到就麻烦了. 其实就是一种逆向思维:最后结果肯定是这样子: WBWBWBWB... BWBWBWBW... WBWBWBWB... ... 里面有“-”的地方改成“-”就行了. 但是我开始是正着想的,想每个点怎么处理,这还要看它周围点的状态,越想越麻烦... 这题中体现的正难则反的逆向思维很值得学习. #include<iostream> #include<cstdio> #include<cstdlib> #include<cs

Codeforces Round #254(div2)B

就是看无向图有几个连通块,答案就是2n-num. 范围很小,就用矩阵来存图减少代码量. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #inc

Codeforces Round #260(div2)C(递推)

有明显的递推关系: f[i]表示i为数列中最大值时所求结果.num[i]表示数i在数列中出现了几次. 对于数i,要么删i,要么删i-1,只有这两种情况,且子问题还是一样的思路.那么很显然递推一下就行了:f[i]=max(f[i-1],f[i-2]+i*num[i]); 这里技巧在于:为了防止麻烦,干脆就所有数的出现次数都记录一下,然后直接从2推到100000(类似于下标排序),就不用排序了,也不用模拟删除操作了.这一技巧貌似简单,但实际上临场想出来也需要点水平. #include<iostrea

Codeforces Round #289 Div2 E

Problem 给一串长度为N的字符串,对于每个字符,若字符为元音,则权值为1,否则为0.一个子串的权值定义为该串所有字符权值之和除以字符个数,一个母串的权值定义为所有子串的权值之和.求母串的权值. Limits Time Limit(ms): 1000 Memory Limit(MB): 256 N: [1, 5*10^5] 字符集: 'A'-'Z' 元音: I E A O U Y Solution 考虑每个元音字符对母串的贡献,可以找出规律. More 举"ABCDOEFGHKMN"

Codeforces Round #403 div2 C. Andryusha and Colored Balloons

题目链接:Codeforces Round #403 div2 C. Andryusha and Colored Balloons 题意: 给你一棵n个节点的树,然后让你染色,规定相连的三个 节点不能同色,问需要的最少颜色,并输出其中一种方案. 题解: 因为只有相邻3个节点不同色. 所以直接DFS,每个节点都从1开始. 然后ans[v]!=ans[u]!=ans[fa]就行. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i&

CodeForces Round#229 DIV2 C 递推DP

对这道题目也只好说呵呵了,没注意k的范围最大才10,所以昨晚纠结了很久,没什么好的方法来处理,后来无奈想去翻翻题解,发现人家开头就来了句,因为k的范围比较小 所以.........我只好暂停马上回头看看题目,是的,k比较小所以完全可以先在询问前预处理DP一遍, DP就比较清晰了,dp[i][j]  (i>=0 && i<k,,,,j>=i && j <=n)代表意义呢 以i为开头的  区间[1,j]注意 是 1~j的 所需要的操作数,题目问的是最小操

codeforces round#259 div2 B题(KMP)

先上链接:http://codeforces.com/contest/454/problem/B B. Little Pony and Sort by Shift time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output One day, Twilight Sparkle is interested in how to sort a se