感动我妈一整年,这几天进行贪心专题,小白却不“白”的我刷到一个类似此题的题然后脑抽过不来,逻辑有问题(分析还是没有耐心做题),今早又刷纪念组发现是同类型题,于是又想了想,终于过了!!!
题目描述
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
输入格式
共 n+2n+2 行:
第一行包括一个整数 ww,为每组纪念品价格之和的上上限。
第二行为一个整数 nn,表示购来的纪念品的总件数 GG。
第 3\sim n+23∼n+2 行每行包含一个正整数 P_iP
i
表示所对应纪念品的价格。
输出格式
一个整数,即最少的分组数目。
下面说我的思路:先把输入的数据快排一下(sort),然后遍历一遍:假设每个人都是单独的一组,然后某个人符合条件后可以来(白嫖),所以遍历的时候检查这个人是否以经在某一组,如果没有,就给他一组,然后从后往前找,找到第一个符合条件的人,把它加入这个组~~最后输出ans就行了,至于为什么要先快排然后从后往前遍历找符合条件的人,原因是贪心呀,要尽可能把给定空间贪心的用完,这是局部最优解,然后才能得到整体最优解
举个例子:有四个人坐船,每条船做多承载6kg,这四个人体重分别是2 2 4 4 如果排好序依次坐则需要三条船 即(2,2)(4)(4) 显然第一条船浪费了空间,没有最大化利用,就是不贪心~,所以要贪心只能是某种程度上的“一大一小” 大概意思就是这样,代码如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
int x,y,ans=0;
cin>>x>>y;
int a[y];
for(int i=0;i<y;i++)
cin>>a[i];
sort(a,a+y);
for(int i=0;i<y;i++)
{
if(a[i]){
ans++;
for(int j=y-1;j>i;j--)
{
if(a[j]&&a[i]+a[j]<=x)
{a[j]=0;break;
}
}
a[i]=0;
}
}
cout<<ans;
return 0;
}