修理牛棚
题目描述
在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。好在许多牛正在度假,所以牛棚没有住满。有些牛棚里有牛,有些没有。所有的牛棚有相同的宽度。自顶遗失以后,农民约翰必须尽快在牛棚之上竖立起新的木板。他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板。农民约翰想将他购买的木板总长度减到最少。给出 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了!为自己鼓掌!!!
自古深情留不住,唯有套路得人心。。。