纪念品分组 2007年NOIP全国联赛普及组

题目描述

       元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。

你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

输入输出格式

输入描述:

包含n+2行:

第1行包括一个整数w,为每组纪念品价格之和的上限。

第2行为一个整数n,表示购来的纪念品的总件数。

第3~n+2行每行包含一个正整数pi (5 <= pi <= w),表示所对应纪念品的价格。

输出描述:

仅一行,包含一个整数,即最少的分组数目。

输入输出样例

输入样例#1:

100

9

90

20

20

30

50

60

70

80

90

输出样例#1:

6

思路

先将数据快排,然后for循环将第一个与最后一个相加,如果得数不大于纪念品价格之和的上限,第一个与最后一个为一组。否则,将第二个与最后一个匹配,以此类推。

代码

#include<stdio.h>
long long a[30010];
void qsort(int l,int r)
{
    int i,j,mid,p;
    i=l;j=r;
    mid=a[(l+r)/2];
    do
    {
        while(a[i]<mid)
          i++;
        while(a[j]>mid)
          j--;
        if(i<=j)
        {
            p=a[i];
            a[i]=a[j];
            a[j]=p;
            i++;j--;
        }
    }while(i<=j);
    if(l<j)
      qsort(l,j);
    if(i<r)
      qsort(i,r);
}
int main()
{
    long long n,i,w,k=0,j,l;
    scanf("%lld%lld",&w,&n);
    for(i=1;i<=n;i++)
       scanf("%lld",&a[i]); 
    qsort(1,n);
    l=1;
    for(i=n;i>=l;i--)
    {
        if(a[i]+a[l]<=w)
            l++;
        k++;
    }
    printf("
%lld",k);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/soul-love/p/5271591.html