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.app
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.this
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.spa
The second line contains nn integers a1,a2,…,ana1,a2,…,an (−109≤ai≤109−109≤ai≤109) — the array aa.xml
Print one integer — the maximum possible beauty of array aa after multiplying all values belonging to some consecutive subarray xx.blog
5 -2 -3 8 -2 1 -6
22
12 -3 1 3 3 7 1 3 3 7 1 3 3 7
42
5 10 -1 -2 -3 -4 -5
0
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]).ip
In the second test case we don't need to multiply any subarray at all.ci
In the third test case no matter which subarray we multiply, the beauty of array will be equal to 0.get
題意 : 讓你選擇一段區間,將區間中的每一個值乘以X,求此時的最大區間和input
思路分析 :it
比賽的時候想了一個作法,X若爲正數,就是正常的求個最大區間和*X,但如果非正數時,當時想的是找到整個序列中最大連續的負的區間和將其乘以X再加上區間的左右倆個端點分別向倆端能夠擴展到的最大連續整數和,這個預處理一下就行,WA掉了,後面想明白了
假設答案是某段區間最終要乘以X,那麼最終答案會是 sum[l, r]*x+qian[l-1]+hou[r+1]
再作進一步的化簡 sum[r]-sum[l-1]+qian[l-1]+hou[r+1] , 移項 sum[r]+hou[r+1]+(qian[l-1]-sum[l-1]) 那麼只須要維護倆端的最大值便可
ll n, x; ll a[maxn]; ll f[maxn]; ll qian[maxn], hou[maxn], sum[maxn]; void solve2(){ for(ll i = 1; i <= n; i++){ sum[i] += sum[i-1]+a[i]; } ll last = n+1; for(ll i = n; i >= 1; i--){ if (a[i] >= 0){ hou[i] = max(a[i]+sum[last-1]-sum[i]+hou[last], a[i]); last = i; } } ll first = 0; for(ll i = 1; i <= n; i++){ if (a[i] >= 0){ qian[i] = max(a[i]+sum[i-1]-sum[first]+qian[first], a[i]); first = i; } } ll a1 = 0, a2 = 0; ll ans = hou[1]; for(ll i = 1; i <= n; i++){ ll num = qian[i-1]-x*sum[i-1]; a1 = max(a1, num); ll num2 = x*sum[i]+hou[i+1]+a1; ans = max(ans, num2); } printf("%lld\n", ans); } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); cin >> n >> x; for(ll i = 1; i <= n; i++){ scanf("%lld", &a[i]); } solve2(); return 0; }
正解應該是作個DP,
dp[i][0] 表示以 i 位置爲結尾的最大連續區間和是多少;
dp[i][1] 表示 i 位置 * X 的最大連續區間和是多少
dp[i][2] 表示 i 位置是 a[i],但其前面有一段是乘過X的,此時的最大連續區間和
代碼示例:
ll n, x; ll a[maxn]; ll dp[maxn][3]; int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); cin >> n >> x; ll ans = 0; for(ll i = 1; i <= n; i++){ scanf("%lld", &a[i]); dp[i][0] = max(dp[i-1][0]+a[i], a[i]); dp[i][1] = max(a[i]*x+max(dp[i-1][0], dp[i-1][1]), a[i]*x); dp[i][2] = max(a[i]+max(dp[i-1][1], dp[i-1][2]), a[i]); ll f = max(dp[i][0], max(dp[i][1], dp[i][2])); ans = max(ans, f); } cout << ans << endl; return 0; }