修理牛棚|USACO|CodeVS 2079|贪心算法

题目链接点击此处

牛棚问题:

【问题描述】

在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没有住满。 剩下的牛一个紧挨着另一个被排成一行来过夜。 有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。 自门遗失以后,农民约翰必须尽快在牛棚之前竖立起新的木板。他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板,农民约翰想将他购买的木板总长度减到最少。

M(1<= M<=50)可能买到的木板最大的数目;

S(1<= S<=200),牛棚的总数;

C(1 <= C <=S) 牛棚里牛的数目,和牛所在的牛棚的编号stall_number(1 <= stall_number <= S),计算拦住所有有牛的牛棚所需木板的最小总长度。

输出所需木板的最小总长度作为的答案。

【输入格式】

第 1 行: M ,S 和 C(用空格分开)

第 2 到 C+1行: 每行包含一个整数,表示牛所占的牛棚的编号。

【输出格式】

单独的一行包含一个整数表示所需木板的最小总长度。

【样例输入】

4 50 18

3

4

6

8

14

15

16

17

21

25

26

27

30

31

40

41

42

43

【样例输出】

25 

【分析】

输入的数据未必排好序,因此先对输入的数据排序;

要想木板距离最小,也就是使每两个区间的空隙最大:

如 1,2,3,8,9,10

  m = 2;

显然3与8之间的距离最大,就用总距离 - 3与8之间的距离 = 10(max) - 1(min) + 1(得到最大距离) - 8 - 3 - 1得到此时最小木板长度,

也就是相当于1,2,3 与 8,9,10分为两组,共执行了 m-1次分配。

 

【代码】

 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 
 5 bool cmp(const int& a, const int& b) {
 6     return a > b;
 7 }
 8 int main() {
 9     int m, s, c;
10     scanf("%d %d %d", &m, &s, &c);
11 
12     std::vector<int> nodes, distance;
13     for(int i = 0, u; i < c; i++) {
14         scanf("%d", &u);
15         nodes.push_back(u);
16     }
17     sort(nodes.begin(), nodes.end());
18     for(int i = 0; i != nodes.size() - 1; i++) {
19         int tmp_dis = nodes[i+1] - nodes[i] - 1;
20         if(tmp_dis > 0) {
21             distance.push_back(tmp_dis);
22         }
23     }
24     sort(distance.begin(), distance.end(), cmp);
25     int ans = nodes[nodes.size()-1] - nodes[0] + 1;
26     
27     for(int i = 0; i < m - 1 && i < distance.size(); i++) {
28         ans -= distance[i];
29     }
30     printf("%d", ans);
31 }

代码说明:nodes,有牛的牛棚,并进行一次排序以取得按照顺序的牛棚编号。

      distance, 每两个牛棚间的间隙,计算方法为 第二个牛棚编号 - 第一个牛棚编号 - 1

                  ans,初值为区间总长度,执行m-1次循环以获得最后剩下的长度。

 

posted @ 2016-05-12 20:47  UEdge  阅读(412)  评论(0编辑  收藏  举报