题目描述
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
输入格式
共 n+2 行:
第一行包括一个整数 w,为每组纪念品价格之和的上上限。
第二行为一个整数 n,表示购来的纪念品的总件数 G。
第 3 n+2 行每行包含一个正整数 Pi 表示所对应纪念品的价格。
输出格式
一个整数,即最少的分组数目。
输入输出样例
输入 #1
100 9 90 20 20 30 50 60 70 80 90
输出 #1
6
说明/提示
50% 的数据满足:1≤n≤15。
100% 的数据满足:1≤n≤3×104,0≤w≤200,0≤Pi≤w。
/*
* @Description: To iterate is human, to recurse divine.
* @Autor: Recursion
* @Date: 2022-03-06 19:05:43
* @LastEditTime: 2022-03-06 19:10:00
*/
#include<bits/stdc++.h>
using namespace std;
int w,n,a[(int)1e6+10];
int main()
{
while(cin>>w){
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
int low=0,high=n-1;
int ans=0;
sort(a,a+n);
while(low<=high){
if(low==high){
ans++;
break;
}
if(a[low]+a[high]>w){
ans++;
high--;
continue;
}
ans++;
low++;
high--;
}
cout<<ans<<endl;
}
}
看不懂证明啦贪心算法证明: 对于
a[i...j]
问题,如果存在最优解 SS,但是 a_iai 和 a_jaj 的分组不符合上述贪心选择过程。会有以下几种情况:
- 如果 a_i + a_j > wai+aj>w,a_jaj 也不可能与其他任何 a_kak, i < k < ji<k<j 一组。 a_jaj 只能单独一组。这是符合贪心选择性质的。
- 如果 a_i + a_j \leq wai+aj≤w, 在最优解中,a_jaj 并不与 a_iai 一组,
- a_jaj 单独一组,这时候如果最优解的 a_iai 仍然孤单, 那么将他俩合为一组,最优解的分组数减一,居然优于最优解,矛盾。
- a_jaj 单独一组, a_iai 与另一个 a_kak 一组,这时候,将 a_iai 从 a_kak 身边拆开,再与 a_jaj 一组,所得分组数不变,新的解 S' = SS′=S,a_iai 和 a_jaj 一组是符合贪心选择性质的,贪心选择可以得到最优解。
- a_jaj 与 a_kak 一组,a_iai 单独一组,交换 a_iai 和 a_kak, 不难看出 S' = SS′=S
- a_jaj 与 a_kak 一组, a_iai 与 a_mam 一组,交换 a_kak 与 a_iai 之后, a_i + a_j \leq wai+aj≤w, a_k + a_m \leq a_k + a_j \leq wak+am≤ak+aj≤w, S' = SS′=S,