修理牛棚

在一个夜黑风高,下着暴风雨的夜晚,farmer John的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没
有住满。 牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜。 有些牛棚里有牛,有些没有。 所有的牛棚有
相同的宽度。 自门遗失以后,farmer John必须尽快在牛棚之前竖立起新的木板。 他的新木材供应商将会供应他任
何他想要的长度,但是吝啬的供应商只能提供有限数目的木板。 farmer John想将他购买的木板总长度减到最少。
给出:可能买到的木板最大的数目M(1<= M<=50);牛棚的总数S(1<= S<=200); 牛棚里牛的总数C(1 <= C <=S);和牛
所在的牛棚的编号stall_number(1 <= stall_number <= S),计算拦住所有有牛的牛棚所需木板的最小总长度。 输
出所需木板的最小总长度作为答案。

Input

1 行: 木板最大的数目M ,牛棚的总数S 和 牛的总数C(用空格分开)  
2 到 C+1行:  每行包含一个整数,表示牛所占的牛棚的编号。

Output

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

Sample Input

4 50 18
3 
4 
6 
8 
14
15 
16 
17 
21
25 
26 
27 
30 
31 
40 
41 
42 
43

Sample Output

25
[ 一种最优的安排是用板拦牛棚3-8,14-21,25-31,40-43.]

sol:如果一个有牛的牛棚一块木板,总长度肯定最小。但题目限定了木板的块数,那我们就要考虑每块木板的起止位置,用一个较长的木板的时候,会把没有牛的牛棚也覆盖了,这样就会造成浪费,我们要是木板总长度最小,则需要浪费最少。m块木板,有m-1个间隔,我们只需要把所有没有牛的区间牛的头数算出来,按从大到小的顺序排列,然后依次删除前m-1个即可。用总的牛的头数-删除的牛的头数,即为答案。注意:起始时输入的每头牛的序号不一定有序,应先排序。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int a[210],d[210];
 7 int ans,m,s,c;
 8 bool cmp(int a,int b){return a>b;}
 9 int main()
10 {
11     scanf("%d%d%d",&m,&s,&c);
12     for(int i=1;i<=c;i++)
13         scanf("%d",&a[i]);
14     sort(a+1,a+1+c);//对c头牛的编号排序 
15     for(int i=1;i<=c-1;i++)
16     //分别计算出1~c头牛相邻牛棚号间的间隔,即两头牛之间没有牛的牛棚个数 
17         d[i]=a[i+1]-a[i]-1;
18     sort(d+1,d+c,cmp);//按间隔从大到小排序 
19     ans=a[c]-a[1]+1;//ans初始值为第一头牛到第c头牛的编号区间一共包含多少个牛棚 
20     for(int i=1;i<=m-1;i++)//ans依次减去前m-1个区间的没有牛的牛棚数 
21         ans-=d[i];
22     printf("%d",ans);
23     return 0;
24 }
 
 
 
原文地址:https://www.cnblogs.com/cutepota/p/12145554.html