列表

详情


NC13888. Maximize The Beautiful Value++

描述

The term of this problem is the same as the problem "Maximize The Beautiful Value", the only exception — The sequence may not necessary to to non-decreasing.
"Maximize The Beautiful Value": https://ac.nowcoder.com/acm/problem/13887

输入描述

 The first line contains an positive integer T(1≤T≤10), represents there are T test cases. 
 For each test case: 
 The first line contains two positive integers n,k(1≤n≤105,1≤k<n),the length of the sequence ,the least steps you need to move. 
 The second line contains n integers a1,a2…an(1≤ai≤108) - the sequence.

输出描述

For each test case, you should output the max F(n).

示例1

输入:

4
5 3
1 1 3 4 5
5 2
1 1 3 4 5
5 1
1 1 3 4 5
5 3
3 5 4 1 1

输出:

46
50
53
43

说明:

In the forth example, you can move the fifth number 1 for 4 steps and then the sequence becomes [1,3,5,4,1]

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java 解法, 执行用时: 755ms, 内存消耗: 33640K, 提交时间: 2023-04-04 13:29:48

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    private static long[] sum;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        long T = Integer.parseInt(br.readLine());
        while (T-- > 0) {
            String[] reading = br.readLine().split(" ");
            int n = Integer.parseInt(reading[0]);
            int k = Integer.parseInt(reading[1]);
            long[] arr = new long[n + 1];
            sum = new long[n + 1];
            int[] queue = new int[n + 1];
            long res = 0;
            int head = 0;
            int tail = 0;
            reading = br.readLine().split(" ");
            for (int i = 1; i <= n; i++) {
                arr[i] = Integer.parseInt(reading[i - 1]);
                sum[i] = sum[i - 1] + arr[i];
                res += arr[i] * i;
            }
            long temp = 0;
            for (int i = k + 1; i <= n; i++) {
                while (tail - head >= 2 && cmp(queue[tail - 2], queue[tail - 1], i - k)) {
                    tail--;
                }
                queue[tail++] = i - k;
                int left = head;
                int right = tail - 1;
                while (left != right) {
                    int mid = (left + right) / 2;
                    if (check(arr[i], queue[mid], queue[mid + 1])) {
                        left = mid + 1;
                    }
                    else {
                        right = mid;
                    }
                }
                temp = Math.max(temp, res + sum[i - 1] - sum[queue[left] - 1] - arr[i] * (i - queue[left]));
            }
            System.out.println(temp);
        }
    }

    private static boolean check(long x, int i, int j) {
        return x * (j - i) > sum[j - 1] - sum[i - 1];
    }

    private static boolean cmp(int i, int j, int k) {
        return (sum[k-1]-sum[j-1])*(j-i)<=(sum[j-1]-sum[i-1])*(k-j);
    }
}

C++11(clang++ 3.9) 解法, 执行用时: 484ms, 内存消耗: 2020K, 提交时间: 2019-07-28 10:14:31

#include <iostream>
#include <stdio.h>
using namespace std;
typedef long long ll;
const int N=1e5+2;
ll a[N],q[N],p[N];
ll n,k;

bool judge(ll i,ll x1,ll x2)
{
    if((p[x1]-p[x2])>a[i]*(x1-x2))
        return true;
    return false;
}

bool judge2(ll i,ll x1,ll x2)
{
    if((p[i]-p[x1])*(x2-x1)<(p[x2]-p[x1])*(i-x1))
        return true;
    return false;
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        p[0]=0;ll sum=0;ll ans=0;
        cin>>n>>k;
        for(int i=1;i<=n;i++ )
        {
            cin>>a[i];
            p[i]=p[i-1]+a[i];
            sum+=a[i]*i;
        }
        int l=1;int r=1,ra=1;q[1]=0;
        for(int i=1+k;i<=n;i++)
        {
            r=ra;
            l=1;
            while(l<r-1)
            {
                int mid=(l+r)/2;
                if(judge(i,q[mid],q[mid+1]))
                    l=mid;
                else
                    r=mid-1;
            }
            if((l==ra)||(!judge(i,q[l],q[l+1])))l--;
            ans=max(ans,sum+p[i]-p[q[l+1]]-a[i]*(i-q[l+1]));
            while(1<ra&&judge2(i-k,q[ra-1],q[ra]))ra--;
            q[++ra]=i-k;
        }
        cout <<ans<< endl;
    }
    return 0;
}

上一题