P1209 [USACO1.3] 修理牛棚 Barn Repair

题目分析

有c头牛,s个牛棚,给出每个牛住的牛棚的编号,给出木板的最大数量,求要拦住所有的牛需要的最小总长度。

要拦住所有牛是指什么呢?

我们要所有住牛的房子都被木板覆盖到(不能有住牛的房子露在外面)。

但是:

· 最多只能用 m 块木板,即木板的块数是确定的,木板的长度是你需要控制的

· 要所有木板的总长度最短

比如:假设 m=3 块木板,牛住在 3,4,6,8,14,15,16,17

求解思路

其实在做题时,可以先不考虑限制条件,题目有时候要清晰一点

比如,先考虑

1.有无限块木板

那么只有有牛的地方覆盖

2.先考虑只有一块木板,

木板覆盖的长度就是从一个牛的窝到最后一头牛的窝

3. 1块木板 增加到两块木板,从哪里断开呢,节省下来的又是哪里?

从这个图可以看出,最开始有一大块木板(红色部分)覆盖了牛住的牛棚,如果此时木板数量变为两块,最理想的状态是断开8-14中间的部分,因为这一段空的最多,断开这一部分,可以节省最大的长度。

4.2块木板增加到3块木板

这里我们断开的有两个选择,4后面断开,6后面断开,但这两处的断开都只能节省一个单位长度的木板。一样的。

综上,我的想法是

记录空格的长度,从小到大排序,选前m-1的空格长度,从总的长度中减去。

即:

  • 从边界想:m=1 时什么样,m=c 时什么样
  • 看增加木板能带来什么好处:发现是省掉间隔
  • 省掉的间隔越大,节省越多 → 优先省大间隔
  • 证明:因为间隔是独立的,选大的肯定比选小的好

这就是贪心策略的发现过程:先理解操作的影响,再找最大化收益的方式。

代码实现

cpp 复制代码
#include <iostream>
#include <algorithm>
using namespace std;
int cows[205], g[205],ans=0; 
int main() {
    int m, s, c;
    cin >> m >> s >> c;
    
    for (int i = 0; i < c; i++) {
        cin >> cows[i];
    }
    // 特殊情况:如果木板数量大于等于牛的数量
    // 每头牛单独一个木板,总长度就是牛的数量
    if (m >= c) {
        cout << c << endl;
        return 0;
    }
    
    sort(cows, cows + c);
    
   //(1)1个牛棚用多长的木板 
    ans = cows[c-1] - cows[0] + 1;
    
    // (2)计算相邻牛棚之间的间隔,从小到大排序 
   
    for (int i = 1; i < c; i++) {
        g[i-1] = cows[i] - cows[i-1] - 1;
    }    
    sort(g, g + c-1, greater<int>());
    
    // 减去前 m-1 个最大的间隔
    for (int i = 0; i < m-1; i++) {
        ans-= g[i];
    }
    
    cout<<ans<< endl;
    
    return 0;
}
相关推荐
散峰而望38 分钟前
【算法练习】算法练习精选:陶陶摘苹果(基础+升级)、Music Notes、字串变换,你能AC几道?
数据结构·c++·算法·leetcode·贪心算法·github·动态规划
暗夜猎手-大魔王44 分钟前
转载--Hermes Agent 04 | Agent 主循环:一次对话背后发生了什么
人工智能·python·算法
手写码匠1 小时前
华为云Flexus+DeepSeek征文|基于华为云Flexus X实例 + Dify + DeepSeek 构建企业级智能知识库问答系统实战
人工智能·深度学习·算法·aigc
吴可可1231 小时前
Win7上开发CAD2004自定义实体全解析
c++·算法
YXXY3131 小时前
二叉树中的深搜算法介绍
算法
zz34572981131 小时前
C语言中字符串常量存储位置
c语言·开发语言·算法·青少年编程
noipp1 小时前
推荐题目:洛谷 P16510 [GKS 2015 #C] gRanks
java·c语言·开发语言·c++·python·算法
菜菜的顾清寒2 小时前
力扣HOT100(50)动态规划-零钱兑换
算法·leetcode·动态规划
周末也要写八哥2 小时前
三分钟读懂:如何解决做题数量不足的问题?
算法
8Qi82 小时前
LeetCode 148. 排序链表 —— 解法二:自底向上归并(迭代,O(1) 空间)
数据结构·算法·leetcode·链表·归并·迭代