[洛谷]P1094 纪念品分组(#贪心 -1.3)

题目描述

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。

你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

输入输出格式

输入格式:

共 n+2n+2 行:

第 11 行包括一个整数 ww ,为每组纪念品价格之和的上上限。

第 22 行为一个整数 nn ,表示购来的纪念品的总件数 GG 。

第 33 至 n+2n+2 行每行包含一个正整数 P_i(5 \le P_i \le w)Pi(5Piw) 表示所对应纪念品的价格。

输出格式:

一个整数,即最少的分组数目。

思路

贪心+排序,这题。

本题的贪心策略就是:然后定义2个变量l,r;分别从a数组左边和右边向中间走[开始模拟],每次走都尽量让最大的和最小的分为一组[排过序后]。如果不行,就让最大的单独分为一组。等l,r跑完,贪心也就完成,分成最少的组了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#define repeat(i,a,b) for(i=a;i<=b;i++)//为了省事而已
using namespace std;
int main()
{
	int n,m,i,a[30001]={},r,l,s=0;
	scanf("%d%d",&n,&m);//readline1
	repeat(i,1,m)
	{
		scanf("%d",&a[i]);//readline2
	}
	sort(a+1,a+m+1);//排序是必须的,不然没法进行贪心策略
	l=1,r=m;//定义2个变量,一个从左跑,一个从右跑
	while(r>=l)//开始进行贪心策略,如果右边的r已经小于l,贪心结束
	{
		if(a[l]+a[r]<=n)//如果当前指向的a数组,最小的和最大的可以成为一组(≤n)
		{
			l++;//向右进一位,等待下一次判断
			r--;//向后进一位,等待下一次判断
			s++;//可以分组,于是累加器+1
		}
		else//如果当前指向的a数组,最小的和最大的不能成为一组(>n)
		{
			r--;//向后进一位,等待和a[l]进行判断(也就是下一次是a[r-1]和a[l]判断)
			s++;//可以单独分组,累加器+1
		}
	}
	printf("%d",s);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/apro1066/article/details/80489757
今日推荐