#174. 修理牛棚

修理牛棚

题目描述

在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。好在许多牛正在度假,所以牛棚没有住满。有些牛棚里有牛,有些没有。所有的牛棚有相同的宽度。自顶遗失以后,农民约翰必须尽快在牛棚之上竖立起新的木板。他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板。农民约翰想将他购买的木板总长度减到最少。给出 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: 每行包含一个整数,表示牛所占的牛棚的编号。

输出格式

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

样例数据

input

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

output

25

注释

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

题目分析:刚拿到一道题目首先要做的就是仔细读题,然后再是对这道题目进行合理的思考以及分析。这道题就是一道比较明显的贪心思想的题目。想要把木板长度节省到最小,主要不在于牛的数量,而在于如何最节约地分配木板。说白了就是要把用了木板却没有牛的空牛棚的数量尽量减到最少(因为木板是有限的,并且不能被截断),贪就贪在每次只挑最多的部分连续空牛棚。

大体思路:首先把从第一个有牛的牛棚开始,到最后一个有牛的牛棚结束,把所有牛棚全部填满(视为有牛)。接着计算出牛棚之间连续的空牛棚,并进行排序。再拿总长度减去一部分较大的空牛棚数量,这道题目就AC了。。。。。。

真的辣么简单吗???

代码如下:

#include<bits/stdc++.h>

using namespace std;

int main()

{

   inta[201],b[201],i,j,m,s,c,p=0,q=0;//两个数组分别装牛和空牛棚数量

   cin>>m>>s>>c;

   for(i=1;i<=c;i++)cin>>a[i];

   sort(a+1,a+c);//注意!刚刚读入的牛的序号不是有序的,必须排序!!!

   for(i=1;i<=c-1;i++)b[i]=a[i]-a[i-1];//计算连续空牛棚的数量并存入

   sort(b+1,b+c);//这里也要再次排序,用来累加

   if(c<=m){cout<<c; return 0;}//如果木板比牛还多,当然就直接输出

   for(i=1;i<m;i++)p+=b[c-i]-1;//几个较大空牛棚数量的累加。注意!必须减1,因为间隔数比距离小1,如:4-3=1

实际只有0个间隔!!!

q=a[c]-a[1]+1;//计算第一个有牛的牛棚,到最后一个有牛的牛棚的总长度。注意!必须加1,因为牛棚序号不为一!!!

   cout<<q-p<<endl;//减去两数相减就得出了结果

}

哟!我居然打完了,还AC了!为自己鼓掌!!!

自古深情留不住,唯有套路得人心。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值