题目大意:
有s个牛棚,其中c个有牛,共有m个任意长度的木板用来封住所有有牛的牛棚。要求编程求出至少需要多长的木板。
思路:
尽量增加木板数量以节约木板长度,最佳情况是一个木板封住一个有牛的牛棚,即用c个木板。总长度为c个单位长度。
若木板数量小于c,那么最多可以用m个木板。可以想象为将一个“从序号最小的牛棚一直到序号最大的牛棚的全部封住的木板”分成m份,也就是去掉其中m-1段。
按照贪心思想,应该按由大到小顺序去掉前m-1个“两个相邻有牛的牛棚之间的间隔”。
代码:
/* ID: lujunda1 LANG: C++ PROG: barn1 */ #include<iostream> #include<stdio.h> #include<cstring> #include<cstdio> #include<stdlib.h> using namespace std; int stalls[200],dis[200]; //自定义cmp比较函数,从大到小排序。 int cmp(const void* m,const void* n) { return *(int*)n-*(int*)m; } int main() { freopen("barn1.in","r",stdin); freopen("barn1.out","w",stdout); //分别用min和max记录序号最小和最大的牛棚。 int m,s,c,min=200,max=0; scanf("%d%d%d",&m,&s,&c); for(int i=0;i<c;i++) { scanf("%d",&stalls[i]); min=min<stalls[i]?min:stalls[i]; max=max>stalls[i]?max:stalls[i]; } //当最大木板数量大于等于有牛的牛棚的数量时,可以用一个木板补一个牛棚。 if(m>=c) { printf("%d\n",c); return 0; } //有牛的牛棚的序号可能不是按照顺序给出的,因此需要排序。 qsort(stalls,c,sizeof(stalls[0]),cmp); //将两个牛棚之间的间隔存储起来并按由大到小顺序排序。 for(int i=0;i<c-1;i++) dis[i-1]=stalls[i-1]-stalls[i]-1; qsort(dis,c-1,sizeof(dis[0]),cmp); //sum表示从最小序号的牛棚到最大序号的牛棚所需最长的木板。 int sum=max-min+1; //把一个最长的连续木板分成m份需要去掉中间m-1个部分。 //贪心思想是按照由大到小顺序去掉其中前m-1个间隔。 for(int i=0;i<m-1;i++) sum-=dis[i]; printf("%d\n",sum); }