题目描述
元旦快到了,校学生会让小理负责新年晚会的纪念品发放工作。
为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。
为了保证在尽量短的时间内发完所有纪念品,小理希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
输入格式
第 11 行包括一个整数 w ,为每组纪念品价格之和的上限。
第 2 行为一个整数 n ,表示购来的纪念品的总件数。
第 3行∼3~n+2 行每行包含一个正整数 pi ( 5≤pi≤w ) ,表示所对应纪念品的价格。
输出格式
包含一个整数,即最少的分组数目。
样例输入输出
样例输入
100
9
90
20
20
30
50
60
70
80
90
样例输出
6
数据范围
对于 100% 的数据,保证 1≤n≤30000,80≤w≤200 。
代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int w=sc.nextInt();
int n=sc.nextInt();
int[]arr=new int[n];
for (int i = 0; i <arr.length ; i++) {
arr[i]=sc.nextInt();
}
Arrays.sort(arr);//排序,从小到大,方便比较
/*双指针思想*/
int left=0; //定义左指针
int right=arr.length-1;//定义右指针
int group=0;//定义组数
while(left<right){
if(arr[left]+arr[right]<=w){//如果左右指针之后小于等于价值上限,同时移动左右指针判断下一对元素
left++;
right--;
group=group+1;//表示两个元素可分在一组,组数+1
}else{//如果元素和大于价值上限,只将右指针左移,继续判断
right--;
group=group+1; //此时组数+1与上面含义不同,因为arr[right]不能与其他元素放在一组,只能单独一组,所以组数+1
}
}
if (left==right){//如果左右指针同时指向一个元素
group=group+1;//则将此元素单独用一组放
}
System.out.println(group);//输出最少组数
}
}