1143 纪念品分组
题目描述 Description
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
输入描述 Input Description
包含n+2行:
第1行包括一个整数w,为每组纪念品价格之和的上限。
第2行为一个整数n,表示购来的纪念品的总件数。
第3~n+2行每行包含一个正整数pi (5 <= pi <= w),表示所对应纪念品的价格。
输出描述 Output Description
仅一行,包含一个整数,即最少的分组数目。
样例输入 Sample Input
100
9
90
20
20
30
50
60
70
80
90
样例输出 Sample Output
6
数据范围及提示 Data Size & Hint
50%的数据满足:1 <= n <= 15
100%的数据满足:1 <= n <= 30000, 80 <= w <= 200
思路:将要分发的物品按照从大到小的顺序排序,之后第一个去和最后一个相加,如果小于规定数n,且没有被分过组,则分类总数sum加1,如果不行,那往前一个数一定比最后一个数大,就不用再判断了,也就是第一个数只能单独分一个组,继续第二个数和最后一个未分组的数比(分过组的标记好。),直到所有数都被分组即可
例如样例给的数据:90,90,80,70,60,50,30,20,20(排序后),一知分组不能超过100
首先,90+20>100,不行,90单独分一组,sum=1;
第二,90同理单独一组,sum=2;
第三,80+20==100,那么80和20一组,sum=3;
第四,70+20<100,70和20一组,sum=4;
第五,60+30<100,60和30一组,sum=5;
第六,由于其他所有数都参与了分组,只剩下50自己,所以它自己一组,sum=6;
所以答案为6
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct node
{
int flag;
int num;
}a[30010];
int cmp(node x,node y)
{
if(x.num!=y.num) return x.num>y.num;
}
int main()
{
int i,j,n,m,sum,x;
scanf("%d%d",&n,&m);
memset(a,0,sizeof(a));
for(i=0;i<m;i++)
scanf("%d",&a[i].num);
sort(a,a+m,cmp);
sum=0;
for(i=0;i<m;i++)
{
x=0;
for(j=m-1;j>=0;j--)
{
if(j==i)
continue;
if(a[i].num+a[j].num<=n&&a[j].flag==0&&a[i].flag==0)
{
a[j].flag=1;
a[i].flag=1;
sum++;
x=1;
break;
}
}
if(x==0&&a[i].flag==0){ sum++;}
}
printf("%d\n",sum);
return 0;
}