首页 > 试题广场 >

牛牛与切割机

[编程题]牛牛与切割机
  • 热度指数:3154 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
有一个序列 a_1, a_2, ..., a_n , 牛牛将对这个序列切割一刀(划分分成两个不相交的非空序列,一个序列为 a_1, \dots, a_p,另一个序列为 a_{p+1}, \dots, a_n),牛牛切割的代价为两个序列元素和的乘积。牛牛想知道切割代价最小是多少。

输入描述:
第一行输入一个整数 n,表示序列的长度 2 \leq n \leq 10^6
第二行输入 n 个整数 a_1, a_2, \dots, a_n,表示序列的元素 -10^3 \leq a_i \leq 10^3


输出描述:
输出一个整数表示切割代价最小是多少。
示例1

输入

5
1 2 3 4 5

输出

14

说明

序列被划分为1 和 2 3 4 5,右边和为 14。
示例2

输入

4
2 1 3 4

输出

16

说明

序列被划分为 2 和 1 3 4。

设做序列和为x,总序列和为常数k,则右序列和为k-x;

即问题可等价为:求y=x(k-x)=-x^2+xk的最小值,抛物线开口向下,则其最小值必在两个端点处取得。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        long[] arr = new long[n];
        long totalSum = 0; // 存储序列总元素和
        
        // 读取序列元素并计算总 sum
        for (int i = 0; i < n; i++) {
            arr[i] = in.nextInt();
            totalSum += arr[i];
        }
        
        // 计算两个端点切割的代价(核心:最小值必在这两个切割点中)
        // 切割点1:左序列仅含第1个元素,右序列含剩余n-1个元素
        long cost1 = arr[0] * (totalSum - arr[0]);
        // 切割点2:左序列含前n-1个元素,右序列仅含最后1个元素
        long cost2 = (totalSum - arr[n - 1]) * arr[n - 1];
        
        // 取两个代价的最小值作为结果
        long minCost = Math.min(cost1, cost2);
        System.out.println(minCost);
        
        in.close();
    }
}


编辑于 2025-10-15 10:08:00 回复(0)
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = in.nextInt();
        }

        int[] preSum = new int[n + 1];
        preSum[0] = 0;
        for (int i = 1; i < preSum.length; i++) {
            preSum[i] = arr[i - 1] + preSum[i - 1];
        }
        long sum1 = 0, sum2 = 0;
        long sum = Long.MAX_VALUE;
        for (int i = 0; i < n-1; i++) {
            sum1 = preSum[i + 1] - preSum[0];
            sum2 = preSum[n] - preSum[i + 1];
            sum = Math.min(sum, sum1 * sum2);

        }
        System.out.print(sum);
    }
}


发表于 2025-09-08 11:11:00 回复(0)