# P1209 [USACO1.3] 修理牛棚 Barn Repair
## 题目描述
在一个月黑风高的暴风雨夜,Farmer John 的牛棚的屋顶、门被吹飞了 好在许多牛正在度假,所以牛棚没有住满。
牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜。有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。
自门遗失以后,Farmer John 必须尽快在牛棚之前竖立起新的木板。他的新木材供应商将会供应他任何他想要的长度,但是吝啬的供应商只能提供有限数目的木板。 Farmer John 想将他购买的木板总长度减到最少。
给出 $m,s,c$,表示木板最大的数目、牛棚的总数、牛的总数;以及每头牛所在牛棚的编号,请算出拦住所有有牛的牛棚所需木板的最小总长度。
## 输入格式
一行三个整数 $m,s,c$,意义如题目描述。
接下来 $c$ 行,每行包含一个整数,表示牛所占的牛棚的编号。
## 输出格式
输出一行一个整数,表示所需木板的最小总长度。
## 输入输出样例 #1
### 输入 #1
```
4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43
```
### 输出 #1
```
25
```
## 说明/提示
【数据范围】
对于 $100\%$ 的数据,$1\le m \le 50$,$1\le c \le s \le 200$。
USACO Training Section 1.3
正解
先说题,就是我们需要求的是最少需要木板的长度来把所有的有牛的牛棚竖起木板,这道题是一道经典的模板题,我们可以先从第一个到最后一个模板的长度(也就是一个板子),当成答案,分成m个板子,我们只需要将这一个板子切m-1次就变成m块了,又因为求的是最短,所以我们每次都要找大的切,我们可以把每个相邻板子的差值从大到小排序,找m-1个就可以
#include<iostream>
#include<algorithm>
#include<cstring>using namespace std;
const int N = 210;
int m, s, c;
int pos[N];
int sub[N];
int ans;bool cmp(int a, int b)
{
return a > b;
}int main()
{
cin >> m >> s >> c;for (int i = 1; i <= c; i++) scanf("%d", &pos[i]);
if (m >= c) {
cout << c << endl;
return 0;
}sort(pos + 1, pos + 1 + c);
ans = pos[c] - pos[1] + 1;for (int i = 2; i <= c; i++) {
sub[i - 1] = pos[i] - pos[i - 1]-1;
}sort(sub + 1, sub + 1 + c - 1,cmp);
for (int i = m, j = 1; i > 1; i--, j++) {
ans -= sub[j];
}cout << ans << endl;
return 0;
}
410

被折叠的 条评论
为什么被折叠?



