云计算百科
云计算领域专业知识百科平台

小红书笔试真题 9.17 - 加速窗口收益(C++/Py/Java /Js/Go)

加速窗口收益

小红书 9月17号 笔试真题 第一题

题目内容

推理集群上排着 mmm 项作业,第 ppp 项有一个收益 vpv_pvp​(正数表示划算,负数表示亏本)。
调度允许开一次加速窗口:挑一段连续作业 [L,R][L,R][L,R](1≤L≤R≤m1\\le L\\le R\\le m1≤L≤R≤m),把这段里每一项的收益改成原来的两倍。也可以一次都不开。
窗口用完之后(或者根本没用),再从作业序列里取出一段非空的连续作业,使它们的收益加起来尽量大。请给出这个最大和。
取出的那段至少要包含一项,不能交空段。

输入描述

首行给出正整数 kkk(1≤k≤2×1011\\le k\\le 2\\times 10^{1}1≤k≤2×101),即询问组数。
随后 kkk 行,每行先写出正整数 mmm(1≤m≤2×1051\\le m\\le 2\\times 10^{5}1≤m≤2×105),再跟 mmm 个整数 v1,v2,…,vmv_1,v_2,\\dots,v_mv1​,v2​,…,vm​(∣vp∣≤1000000000|v_p|\\le 1000000000∣vp​∣≤1000000000),即该组作业条数和各项收益。
各组 mmm 加起来不超过 200000200000200000。

输出描述

一行输出 kkk 个整数,相邻两项用空格隔开,依次为每组询问的最大连续收益和。

样例1

输入

2
4 2 -3 4 -1
3 -5 -2 -7

输出

8 -2

说明

  • 第一组:把 [3,3][3,3][3,3](收益 444)翻倍,序列变成 2,−3,8,−12,-3,8,-12,−3,8,−1。最大连续和是单独的 888。
  • 第二组:全是负数,翻倍只会更亏,不开窗口,答案是最大的一项 −2-2−2。

样例2

输入

1
6 1 2 -5 3 -1 4

输出

12

说明
把 [4,6][4,6][4,6](3,−1,43,-1,43,−1,4)翻倍,这段和从 666 变成 121212。左侧 1,2,−51,2,-51,2,−5 接上去会变差,所以最大就是 121212。

题解和思路

思路

实现思路:动态规划

  • 使用f[i]表示以第i个数结尾的连续数组的最大和。
  • 从前往后遍历数组,对于位置i,能取到的最大值为f[i] = max(f(i-1)+ nums[i], nums[i])
  • 按照2逻辑处理,ans为记录出现的最大f值。如果ans > 0 进行ans = ans * 2, 小于0情况不处理。
  • 时间复杂度为O(m)
  • C++

    #include<bits/stdc++.h>
    using namespace std;
    using ll = long long;

    int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int k;
    cin >> k;
    vector<ll> res(k);
    for (int x = 0; x < k; x++) {
    int m;
    cin >> m;
    vector<ll>v(m);
    for (int i = 0; i < m; i++) {
    cin >> v[i];
    }
    ll ans = –1000000006;
    ll last = 0;
    for (int i = 0; i < m; i++) {
    if (last > 0) {
    last = last + v[i];
    } else {
    last = v[i];
    }
    ans = max(ans, last);
    }
    if (ans > 0) {
    ans *= 2;
    }
    res[x] = ans;
    }
    for (int i = 0; i < k; i++) {
    if (i > 0) {
    cout << " ";
    }
    cout << res[i];
    }
    return 0;
    }

    Java

    import java.io.*;
    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int k = sc.nextInt();
    long[] res = new long[k];

    for (int x = 0; x < k; x++) {
    int m = sc.nextInt();

    long[] v = new long[m];
    for (int i = 0; i < m; i++) {
    v[i] = sc.nextLong();
    }

    long ans = –1000000006L;
    long last = 0;

    for (int i = 0; i < m; i++) {
    if (last > 0) {
    last = last + v[i];
    } else {
    last = v[i];
    }

    ans = Math.max(ans, last);
    }

    if (ans > 0) {
    ans *= 2;
    }

    res[x] = ans;
    }

    for (int i = 0; i < k; i++) {
    if (i > 0) {
    System.out.print(" ");
    }
    System.out.print(res[i]);
    }
    }
    }

    python

    import sys

    input = sys.stdin.readline

    k = int(input())

    res = [0] * k

    for x in range(k):
    data = list(map(int, input().split()))
    m = data[0]
    v = data[1:]
    ans = –1000000006
    last = 0

    for i in range(m):
    if last > 0:
    last = last + v[i]
    else:
    last = v[i]

    ans = max(ans, last)

    if ans > 0:
    ans *= 2

    res[x] = ans

    print(*res)

    Javascript

    const readline = require('readline');

    const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
    });

    const input = [];

    rl.on('line', (line) => {
    input.push(line.trim());
    });

    rl.on('close', () => {
    let idx = 0;

    const k = Number(input[idx++]);
    const res = new Array(k);

    for (let x = 0; x < k; x++) {

    const data = input[idx++].split(/\\s+/).map(Number);
    const m = data[0];
    const v = data.slice(1, m + 2);
    let ans = –1000000006;
    let last = 0;

    for (let i = 0; i < m; i++) {
    if (last > 0) {
    last = last + v[i];
    } else {
    last = v[i];
    }

    ans = Math.max(ans, last);
    }

    if (ans > 0) {
    ans *= 2;
    }

    res[x] = ans;
    }

    console.log(res.join(' '));
    });

    Go

    package main

    import (
    "bufio"
    "fmt"
    "os"
    )

    func main() {
    in := bufio.NewReader(os.Stdin)
    out := bufio.NewWriter(os.Stdout)
    defer out.Flush()

    var k int
    fmt.Fscan(in, &k)

    res := make([]int64, k)

    for x := 0; x < k; x++ {
    var m int
    fmt.Fscan(in, &m)

    v := make([]int64, m)
    for i := 0; i < m; i++ {
    fmt.Fscan(in, &v[i])
    }

    var ans int64 = –1000000006
    var last int64 = 0

    for i := 0; i < m; i++ {
    if last > 0 {
    last = last + v[i]
    } else {
    last = v[i]
    }

    if last > ans {
    ans = last
    }
    }

    if ans > 0 {
    ans *= 2
    }

    res[x] = ans
    }

    for i := 0; i < k; i++ {
    if i > 0 {
    fmt.Fprint(out, " ")
    }
    fmt.Fprint(out, res[i])
    }
    }

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 小红书笔试真题 9.17 - 加速窗口收益(C++/Py/Java /Js/Go)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!