题目描述
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
输入描述
输入包含 n+2n+2 行:
第 11 行包括一个整数 ww,为每组纪念品价格之和的上限。
第 22 行为一个整数 nn,表示购来的纪念品的总件数 GG。
第 3\sim n+23∼n+2行每行包含一个正整数 Pi (5 \leq Pi \leq w3)wPi(5≤Pi≤w3)w表示所对应纪念品的价格。
100100%的数据满足: 1 \leq n \leq 300001≤n≤30000, 80 \leq W \leq 20080≤W≤200。
输出描述
仅 11 行,包含一个整数, 表示最少的分组数目合
输入:
100
9
90
20
20
30
50
60
70
80
90
输出:
6
解题思路:
总体思想是贪心
1.第一步先对纪念品价格排序
2.利用尺取法,对最小的和最大的进行判断(也就是纪念品价格数组的头和尾部)
会有两种情况:1.加起来比w大:指向大价格的指针向指向小价格的指针方向挪动,大价格的纪念品只能单独一组;
2.加起来小于等于w,这时候两个指针都向中间靠拢,成为一组,整体循环条件是两个指针是否相等,相等则推出循环,具体代码如下:
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=30001;
int a[maxn];
int main()
{
int w,n,ans=1;
cin>>w;//每组价格上限
cin>>n;//纪念品总件数
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n);
int l=0,r=n-1;
while(l!=r)
{
if(a[l]+a[r]<=w)
{
ans++;//组数
l++;
r--;
}
else
{
r--;
ans++;
}
}
cout<<ans;
return 0;
}