P1094 [NOIP2007 普及组] 纪念品分组

news/2024/9/23 20:11:56/文章来源:https://www.cnblogs.com/ltphy-/p/18427791

[NOIP2007 普及组] 纪念品分组

题目背景

NOIP2007 普及组 T2

题目描述

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

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

输入格式

共 $n+2$ 行:

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

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

第 $3\sim n+2$ 行每行包含一个正整数 $P_i$ 表示所对应纪念品的价格。

输出格式

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

样例 #1

样例输入 #1

100 
9 
90 
20 
20 
30 
50 
60 
70 
80 
90

样例输出 #1

6

提示

$50%$ 的数据满足:$1\le n\le15$。

$100%$ 的数据满足:$1\le n\le3\times10^4$,$80\le w\le200$,$5 \le P_i \le w$。


贪心

重在证明,虽然AC了证明还是模糊

贪心策略:

1.首先对所有物品的价值从小到大进行排序

2.用两个指针,一个指向前端,另一个指向后端;

3.最小的匹配最大的时候分组数最小

4.当 $a_i + a_j > w$时,j--;

说明后面数太大了,只能独立作为一个组

5.当 $a_i + a_j <= w$ 时,i++, j--;

两个数作为一个组

证明:

分情况进行讨论:

首先贪心得到的解是一种可行方案,而最后的最优解是所有可行方案中的最小值,
因此可以证明出 最优解 <= 贪心得到的解

存在最优解S ,他不是按照贪心步骤得到的;

1.$a_i + a_j > w$ 时,由于从小到大进行了排序 $a_i$ 是当前最小的,说明$a_j$不能与其他任何$a_k$为一组,$i < k < j $,因此$a_j$只能独立分组;

2.$a_i + a_j <= w$ ,而最优解中并不是$a_i与a_j$ 一组;

(1)$a_j$ 是独立分组的,并且$a_i$也是独立分组的时候,由于$a_i + a_j <= w$,将它俩合并为同一个组,这时分组数-1,这里可以证明出最优解 >= 贪心得到的解

到这一步我们可知贪心得到的解就是最优解。

进一步说明:
已知 $i < k < j$,

(2)$a_j$ 单独一组,$a_i 与 a_k$ 一组,将$a_i$与$a_k4拆分,再把$a_i$与$a_j$合并,这是分组数不变

(3)$a_j与a_k$ 一组,$a_i$单独一个组,这时候交换$a_i,a_k$, 分组数仍不变

C++ 代码

#include <bits/stdc++.h>
using namespace std;const int N = 3e4 + 10;int w,n;
int a[N];
int ans;int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> w >> n;for(int i = 1; i <= n; i++){cin >> a[i];}sort(a + 1, a + 1 + n);int i = 1,j = n;while(i <= j){if(a[i] + a[j] > w) {ans ++;   //单独作为一个组j--; }else{ans ++;  //两件物品一起作为一个组i++;j--; }}cout << ans << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/802391.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9月23日总结

今天上了数据结构课,学习了线性表的增删改查;正式上了第一节Java课,学习了些Java的基本知识,运行了代码,部分运行结果如下:

动手实验 1

请运行以下代码(TestDouble.java) public class TestDouble { public static void main(String args[]) {System.out.println("0.05 + 0.01 = " + (0.05 + 0.01));System.out.println("1.0 - 0.42 = " + (1.0 - 0.42));System.out.println("4.015 *…

[GXYCTF2019]BabySQli

这题查看源码后发现一个php文件问了ai后发现MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5是一段 base32编码,经过base32解码,base64解码后的结果是select * from user where username = $name 很明显是一个sql语句,在…

以数赋能实景三维创新“科技+文旅”

在数字化时代,科技与文化的融合为我们带来了无限可能。今天,我们将探讨如何利用实景三维技术,推动“科技+文旅”的创新发展。1. 实景三维技术概述实景三维技术,是一种集成了遥感、地理信息系统(GIS)、三维建模等技术的前沿科技。它能够将现实世界的地理信息以三维形式数字…

什么是原子操作?Java如何实现原子操作?

1.什么是原子操作? 我们在学习MYSQL时就了解过原子性,即整个事务是不可分割的最小单位,事务中任何一个语句执行失败,所有已经执行成功的语句也要回滚,整个数据库状态要恢复到执行任务前的状态。Java中的原子性其实就是和数据库中说的相似,就是不可在分割,在我们的多线程…

JAVA基础之八-方法变量作用域和编译器

本文主要讨论方法中变量作用域。不涉及类属性变量、静态变量、线程变量共享等。 虽然知道某类变量的作用域非常重要,但是没有太多需要说的,因为许多东西是显而易见,不言自明。在大部分情况下,或者在老一点版本中,java语法看起来都比较正常,或者说相对古典。 但是随着JAVA…

信息学奥赛复赛复习01-CSP-J2019-01-字符、字符数组、字符串、string、字符串读取

信息学奥赛复赛复习01-CSP-J2019-01-字符、字符数组、字符串、string、字符串读取 PDF文档公众号回复关键字:202409231 2019 CSP-J 题目1 数字游戏 [题目描述] 小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏,小 P 同学想要知道字符串中究竟有多少个 1。 注…

学习高校课程-软件工程-理解需求(ch8)

REQUIREMENTS ENGINEERING 需求工程 Requirements engineering encompasses seven distinct tasks: inception, elicitation,elaboration, negotiation, specification, validation, and management Inception 启动 At project inception, you establish a basic understanding…

局域网远程命令重启电脑

只要知道远程服务器的管理员密码和IP地址,在局域网中的任意一台机器上打开“命令提示符”窗口,运行以下命令:1、获取远程服务器的管理员权限net use IP地址 "管理员密码" /user:administrator2、使用shutdown命令远程重启服务器shutdown /r /t 0 /m IP地址这样的…

Hexo-GitHub部署魔改第一步-config

Hexo-GitHub部署魔改第一步_config.yml 1. config.yml # Hexo Configuration ## Docs: https://hexo.io/docs/configuration.html ## Source: https://github.com/hexojs/hexo/# Site # 设置博客的标题 title: Your Blog Title # 子标题,可选 subtitle: xxxxx # 博客的描述,可…

git credential

远程访问github仓库时,git credential可以帮助我们避免重复输入用户密码并提高安全性。但是在本地计算机切换github用户后,如果不更新git credential,将会导致没有权限访问私有仓库或者push共有仓库。 对于 Windows 用户,打开 控制面板 -> 凭据管理器,找到与 GitHub 相…