首页 > 试题广场 >

农田最大产出评估

[编程题]农田最大产出评估
  • 热度指数:56 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
一位农业科学家正在评估一块狭长试验田的生产潜力。这块试验田被划分为 n 个连续的地块,每个地块都有一个特定的“肥力指数”。
当一组连续的地块被用来种植同一种作物时,整个组的最终产出受到该组中肥力最差的那个地块的限制。这种效应可以用一个“产出系数”来量化,其计算公式为:
产出系数 = 组内最低肥力指数 \times 组内地块数量
作为项目负责人,你需要分析所有可能的连续地块组合,计算它们的产出系数,并找出其中可能达到的最大值,以制定最优的种植计划。

给定一个正整数数组 F,代表了一系列连续地块的肥力指数。你需要计算所有连续非空地块组合的产出系数,并返回其中的最大值。
连续非空地块组合:指一组在原序列中相邻的地块。例如,肥力指数序列为 [10, 20, 30] 的组合包括:
- [10]、[20]、[30]
- [10, 20]、[20, 30]
- [10, 20, 30]

输入描述:
- 第一行:一个整数 n,表示地块的总数,其中 1 \le n \le 10^4
- 接下来 n 行:每行一个整数,代表第 i 个地块的肥力指数 F_i,其中 1 \le F_i \le 10^4


输出描述:
- 输出一个整数,代表所有连续组合中可以达到的最大产出系数。
示例1

输入

8
51
50
50
1
14
32
15
2

输出

150

备注:
本题由牛友@Charles 整理上传
单调栈:一次遍历
import java.util.*;

// 若f[i]为区间[l,r]内的最小值, 要使f[i]*(r-l+1)最大化, 应该向左右延展区间长度
// 单调栈:找f[i]的左侧右侧第一个比f[i]更小的数
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = Integer.parseInt(in.nextLine());
        int[] f = new int[n];
        for (int i = 0; i < n; i++) {
            f[i] = Integer.parseInt(in.nextLine());
        }
        
        Deque<Integer> stack = new ArrayDeque<>(); // 存下标
        stack.offer(-1); // 哨兵:兜底左侧第一个更小数下标-1
        int res = 0;
        for (int i = 0; i <= n; i++) {
            // i==n时取-1:-1逼出栈内剩余元素, n兜底右侧第一个更小数下标n
            int x = (i == n) ? -1 : f[i];
            while (stack.size() > 1 && x < f[stack.peek()]) {
                int r = i, j = stack.pop(), l = stack.peek();
                res = Math.max(res, f[j] * (r - l - 1)); // (l,r)内f[j]最小
            }
            stack.push(i);
        }
        System.out.println(res);
    }
}


发表于 2025-10-12 11:41:03 回复(0)