题目描述

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

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

输入格式

共 n+2 行:

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

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

第 3∼n+2 行每行包含一个正整数 Pi​ 表示所对应纪念品的价格。

输出格式

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

输入输出样例

输入 

100 
9 
90 
20 
20 
30 
50 
60 
70 
80 
90

输出 

6

说明/提示

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

100% 的数据满足:1≤n≤3×104,80≤w≤200,5≤Pi​≤w。

代码

无注释版

#include<bits/stdc++.h>
using namespace std;
int a[30010],f[30010];
int s;
int main(){
	int w;
	cin>>w;
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	int s=0;
	for(int i=1;i<=n;i++){
		if(f[i]==0){
			for(int j=n;j>=1;j--){
				if(f[j]==0&&a[i]+a[j]<=w&&i!=j){
					s++;
					f[j]=1;
					f[i]=1;
					break;
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(f[i]==0) s++;
	}
	cout<<s;
}

有注释版 

#include<bits/stdc++.h>
using namespace std;

int a[30010], f[30010]; // a数组存储纪念品价格,f数组标记纪念品是否已被分组
int s; // 用于统计分组数量(这个全局变量s实际上没有被使用)

int main(){
    int w; // 每组纪念品价格之和的上限
    cin >> w;
    
    int n; // 纪念品的总件数
    cin >> n;
    
    // 读入所有纪念品的价格
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    
    // 将纪念品按价格从小到大排序
    sort(a + 1, a + n + 1);
    
    int s = 0; // 初始化分组计数器(这里重新定义了局部变量s)
    
    // 贪心算法:尝试将最便宜的物品和最贵的物品配对
    for(int i = 1; i <= n; i++){
        if(f[i] == 0){ // 如果第i件物品尚未被分组
            // 从最贵的物品开始检查能否与当前物品配对
            for(int j = n; j >= 1; j--){
                // 如果第j件物品未被分组,且两件物品价格之和不超过w,且不是同一件物品
                if(f[j] == 0 && a[i] + a[j] <= w && i != j){
                    s++; // 增加一个分组
                    f[j] = 1; // 标记第j件物品已被分组
                    f[i] = 1; // 标记第i件物品已被分组
                    break; // 找到配对后跳出内层循环
                }
            }
        }
    }
    
    // 统计未被分组的单独物品(每个单独成为一组)
    for(int i = 1; i <= n; i++){
        if(f[i] == 0) s++;
    }
    
    // 输出最少的分组数目
    cout << s;
    
    return 0;
}
Logo

集算法之大成!助力oier实现梦想!

更多推荐