一整块板覆盖全部牛棚后,贪心地在最大的 C−M 个牛棚间隙处切开,砍掉的总长度恰好等于最小木板总长。
OJ: roj
题目 ID: 2010
难度:入门
标签:贪心排序python
创建: 2026-10-01 02:41
更新: 2026-10-06 09:25
题目描述
编号
数据范围:
思路
先假设用一整块板覆盖最左到最右的有牛牛棚。相邻有牛牛棚之间的空棚间隙如果越大,在这里断开越省长度。因此把间隙从大到小排序,切掉前
参考代码
Python 版:
python
import sys
def main() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
m, s, c = next(data), next(data), next(data)
a = sorted(next(data) for _ in range(c))
# 从“一整块板 [a[0], a[-1]]”开始,允许再切 m-1 刀
gaps = [y - x - 1 for x, y in zip(a, a[1:])]
print(a[-1] - a[0] + 1 - sum(sorted(gaps, reverse=True)[:m - 1]))
main()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-06 09:25
* update_at: 2026-10-06 09:25
*/
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXC = 205;
ll a[MAXC]; // 有牛牛棚编号
ll gaps[MAXC]; // 相邻间隙
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll m, s, c;
cin >> m >> s >> c;
for (int i = 1; i <= c; ++i) cin >> a[i];
sort(a + 1, a + c + 1);
// 整块板覆盖 [a[1], a[c]],然后切最大的 k-1 个间隙
int k = (int)min(m, c); // 实际使用的板数
for (int i = 1; i < c; ++i) gaps[i] = a[i + 1] - a[i] - 1;
sort(gaps + 1, gaps + c); // 升序
reverse(gaps + 1, gaps + c); // 转成降序
ll total = a[c] - a[1] + 1;
for (int i = 1; i <= k - 1 && i < c; ++i) total -= gaps[i];
cout << total << "\n";
return 0;
}