2 条题解

  • 1
    @ 2026-7-23 19:17:56

    我无疑是愤怒的

    • -1
      @ 2026-2-2 22:11:06

      🧠 题意简述

      我们有 N 个牛栏,每个牛栏当前温度是 t[i],奶牛希望的温度是 p[i]。
      空调每次操作可以选择任意一个连续区间 [L, R],将这个区间内所有牛栏的温度 统一 +1 或 -1。

      目标:用最少的操作次数,使得每个牛栏最终温度等于对应奶牛的理想温度。

      💡 核心思想(差分 + 贪心)

      这个问题本质上是一个 区间增减问题,可以用 差分数组 的思想高效解决。

      关键观察:
      每次操作对一个区间 [L, R] 整体 +1 或 -1,相当于在差分数组上:

      • 在位置 L 处 +1(或 -1)
      • 在位置 R+1 处 -1(或 +1)

      但反过来想:如果我们知道每个位置需要变化多少(即 d[i] = p[i] - t[i]),那么最少操作次数就等于 将全零数组通过区间加减变成 d 数组所需的最少操作数。

      而这个问题有一个经典结论:

      最少操作次数 = 所有正的相邻差分之和 更准确地说,设 d[0] = 0,d[i] = p[i] - t[i],构造差分数组 Δ[i] = d[i] - d[i-1],
      则答案就是 Σ max(Δ[i], 0),其中 i 从 1 到 N。

      或者等价地(如本代码所做):

      • 定义 b[i] = p[i] - t[i]
      • 补一个 b[0] = 0,b[n+1] = 0
      • 答案 = 所有 max(b[i] - b[i-1], 0) 的和(i 从 1 到 n+1)

      这其实是在模拟“从左到右构建目标数组”的过程,每次遇到上升(需要增加温度),就必须发起新的操作;下降则可以“复用”之前的降温操作(或不需要新操作)。

      #include <bits/stdc++.h>
      using namespace std;
      const int MAXN = 100010;  // 根据数据范围 N ≤ 100,000
      int need[MAXN];
      int main() {
      	int n;
      	scanf("%d", &n);
      	int p[MAXN], t[MAXN];// p: 目标温度,t: 当前温度
      	for (int i = 1; i <= n; i++)scanf("%d", &p[i]);// 读入目标温度
      	for (int i = 1; i <= n; i++)scanf("%d", &t[i]);// 读入当前温度
      	// 计算每个牛栏需要的变化量(目标温度 - 当前温度)
      	// 如果是正数表示需要升温,负数表示需要降温
      	for (int i = 1; i <= n; i++)need[i] = p[i] - t[i];
      	// 算法核心:计算所有正的相邻差分之和
      	long long ans = 0;
      	// 假设 need[0] = 0(牛栏0不存在,看作温度为0)
      	// 计算 Δ[i] = need[i] - need[i-1]
      	for (int i = 1; i <= n + 1; i++) {
      		int delta = need[i] - need[i - 1]; // need[0]默认为0
      		if (delta > 0)ans += delta;  // 只累加正的差分
      	}
      	printf("%lld\n", ans);// 输出结果
      	return 0;
      }
      
      • 1

      信息

      ID
      3
      时间
      1000ms
      内存
      256MiB
      难度
      8
      标签
      递交数
      24
      已通过
      6
      上传者