【NOIP 2007】纪念品分组

【NOIP 2007】纪念品分组

题目

题目描述

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

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

输入格式

共n+2行:

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

第2行为一个整数n,表示购来的纪念品的总件数G。

第3至n+2行每行包含一个正整数P i​ (5≤P i​ ≤w)表示所对应纪念品的价格。

输出格式

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

输入输出样例

输入 #1 复制
100
9
90
20
20
30
50
60
70
80
90
输出 #1 复制
6

说明/提示

50%的数据满足:1≤n≤15

100%的数据满足:1≤n≤30000,80≤w≤200

分析

(学生会总喜欢搞这些有的没有,真的烦。。。。。。。哈哈说着玩,没进过也不知道。)

题目要求
(把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。)

首先读入,从小到大排序。
我是这样想到,设一个k1=1,k2=n 然后从两头开始 枚举。最后k1==k2 代表枚举结束;

1每次让 k1 + k2 ; 如果 k1 + k2 > 给定的整数w 。那么表示不能合成一个组,那么让k2(大的那个) 单独一组。ans++,k2–;继续
2如果 k1 + k2 <= 给定的整数w,那么表示能合成一个组,k1++,k–; 继续

必须注意,每次k2-- 时,要判断 k2-- 后的k2 与k1是不是 同个数,是代表相撞了,枚举结束;
(文字假装是图片 : -> 数 数 数 k1 k2数数数 <-
,这时 k1 k2已经是相邻了。k2-- 已经没有能再减了。)

还要注意,如果k2–后与k1不是同个数, 让k1++, 这时也要判断 k2 是不是等于k1,是的话 表示他们都指向最后一个数,这个数 只能自己一组了。
(文字假装是图片 : -> 数 数 数 k1 k2数数数 <-
,k2–后,k2来到中间那个数,这时 k1++。那么k1,k2就指向了同一个数, 那么这个数就单独一组啦,同时结束枚举)

代码

#include<iostream>

using namespace std;
#include<algorithm>

int w,n;
int a[30005];

bool cmp(int x,int y){
	return x > y;
}

int main(){
	cin>>w>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];

	}
	sort(a+1,a+1+n);


	int k1=1,k2=n;
	int ans=0;
	while(k1!=k2){
		
		//大的那个单独一组 
		if(a[k1] + a[k2] >w){
			ans++;
			k2--;
		}else{		//两个合成一组 
			ans++;
			k2--;

			if(k1 == k2)break;      
			else k1++;
			
			//剩单个 
			if(k1 == k2) {
				ans++;
				break;
			}
		}
	}
	return 0;
}
发布了75 篇原创文章 · 获赞 1 · 访问量 3659

猜你喜欢

转载自blog.csdn.net/A793488316/article/details/104548203