P15755 [JAG 2025 Summer Camp #1] JAG Box

传送门

题目描述

JAG Box 是一种目前在全世界流行的普通长方体盒子。共有 N N N 个 JAG Box。对于每个 i = 1 , 2 , ... , N i = 1, 2, \ldots, N i=1,2,...,N,第 i i i 个盒子有一个整数重量 A i A_i Ai。

你将通过重复选择一个剩余的盒子并将其插入当前堆叠的最底部来建造一个垂直堆叠。当一个重量为 w w w 的盒子被插入到总重量为 x x x 的现有堆叠底部时,该盒子承受的负载等于 ⌊ x w ⌋ \left\lfloor \frac{x}{w} \right\rfloor ⌊wx⌋。

确定所有盒子可能承受的最小总负载。

输入格式

输入格式如下:

N A 1 A 2 ... A N \begin{aligned} &N \\ &A_1 \ A_2 \ \ldots \ A_N \end{aligned} NA1 A2 ... AN

  • 2 ≤ N ≤ 200   000 2 \leq N \leq 200\,000 2≤N≤200000
  • 1 ≤ A i ≤ 10 9 1 \leq A_i \leq 10^9 1≤Ai≤109 ( 1 ≤ i ≤ N 1 \leq i \leq N 1≤i≤N)
  • 所有输入值均为整数。

输出格式

在一行中输出答案。

输入输出样例 #1

输入 #1

复制代码
5
3 1 4 1 5

输出 #1

复制代码
3

题意

有 N N N 个 JAG Box。对于每个 i = 1 , 2 , ... , N i = 1, 2, \ldots, N i=1,2,...,N,第 i i i 个盒子有一个整数重量 A i A_i Ai。

通过重复选择一个剩余的盒子并将其插入当前堆叠的最底部来建造一个垂直堆叠。当一个重量为 w w w 的盒子被插入到总重量为 x x x 的现有堆叠底部时,该盒子承受的负载等于 ⌊ x w ⌋ \left\lfloor \frac{x}{w} \right\rfloor ⌊wx⌋。

求所有盒子可能承受的最小总负载。

思路

考虑贪心做法,只需按 A i A_i Ai 升序排序即可。

采用邻项交换法证明,设当前的堆叠总重量为 x x x,现有升序排序后两个数 A i , A i + 1 A_i,A_{i+1} Ai,Ai+1( A i ≤ A i + 1 A_i \le A_{i+1} Ai≤Ai+1)。

  1. 顺序放入:负载为 S 1 = ⌊ x A i ⌋ + ⌊ x + A i A i + 1 ⌋ S_1 = \left\lfloor \frac{x}{A_i} \right\rfloor + \left\lfloor \frac{x + A_i}{A_{i+1}} \right\rfloor S1=⌊Aix⌋+⌊Ai+1x+Ai⌋。
  2. 反序放入:负载为 S 2 = ⌊ x A i + 1 ⌋ + ⌊ x + A i + 1 A i ⌋ S_2 = \left\lfloor \frac{x}{A_{i+1}} \right\rfloor + \left\lfloor \frac{x + A_{i+1}}{A_i} \right\rfloor S2=⌊Ai+1x⌋+⌊Aix+Ai+1⌋。

关键引理

对于任意正整数 n , m , k n,m,k n,m,k:

⌊ x + k m ⌋ − ⌊ x m ⌋ ∈ { 0 , 1 } \left\lfloor \frac{x + k}{m} \right\rfloor - \left\lfloor \frac{x}{m} \right\rfloor \in \{0,1\} ⌊mx+k⌋−⌊mx⌋∈{0,1}

  • 若 k ≥ m k \ge m k≥m,则差值一定为 1 1 1;
  • 若 k < m k < m k<m,差值为 0 0 0 或 1 1 1。

接着提出公共项:

S 1 = ⌊ x A i ⌋ + ⌊ x A i + 1 ⌋ + ( ⌊ x + A i A i + 1 ⌋ − ⌊ x A i + 1 ⌋ ) S_1 = \left\lfloor \frac{x}{A_i} \right\rfloor + \left\lfloor \frac{x}{A_{i+1}} \right\rfloor + (\left\lfloor \frac{x+A_i}{A_{i + 1}} \right\rfloor - \left\lfloor \frac{x}{A_{i+1}} \right\rfloor) S1=⌊Aix⌋+⌊Ai+1x⌋+(⌊Ai+1x+Ai⌋−⌊Ai+1x⌋)

S 2 = ⌊ x A i ⌋ + ⌊ x A i + 1 ⌋ + ( ⌊ x + A i + 1 A i ⌋ − ⌊ x A i ⌋ ) S_2 = \left\lfloor \frac{x}{A_i} \right\rfloor + \left\lfloor \frac{x}{A_{i+1}} \right\rfloor + (\left\lfloor \frac{x+A_{i + 1}}{A_i} \right\rfloor - \left\lfloor \frac{x}{A_i} \right\rfloor) S2=⌊Aix⌋+⌊Ai+1x⌋+(⌊Aix+Ai+1⌋−⌊Aix⌋)

  • 因为 A i + 1 ≥ A i A_{i+1} \ge A_i Ai+1≥Ai,所以 ⌊ x + A i + 1 A i ⌋ − ⌊ x A i ⌋ = 1 \left\lfloor \frac{x+A_{i + 1}}{A_i} \right\rfloor - \left\lfloor \frac{x}{A_i} \right\rfloor = 1 ⌊Aix+Ai+1⌋−⌊Aix⌋=1;
  • 因为 A i ≤ A i + 1 A_i \le A_{i+1} Ai≤Ai+1,所以 ⌊ x + A i A i + 1 ⌋ − ⌊ x A i + 1 ⌋ ∈ { 0 , 1 } \left\lfloor \frac{x+A_i}{A_{i + 1}} \right\rfloor - \left\lfloor \frac{x}{A_{i+1}} \right\rfloor \in \{0,1\} ⌊Ai+1x+Ai⌋−⌊Ai+1x⌋∈{0,1}。

于是总有:

⌊ x + A i A i + 1 ⌋ − ⌊ x A i + 1 ⌋ ≤ ⌊ x + A i + 1 A i ⌋ − ⌊ x A i ⌋ ⇒ S 1 ≤ S 2 \left\lfloor \frac{x+A_i}{A_{i + 1}} \right\rfloor - \left\lfloor \frac{x}{A_{i+1}} \right\rfloor \le \left\lfloor \frac{x+A_{i + 1}}{A_i} \right\rfloor - \left\lfloor \frac{x}{A_i} \right\rfloor \Rightarrow S_1 \le S_2 ⌊Ai+1x+Ai⌋−⌊Ai+1x⌋≤⌊Aix+Ai+1⌋−⌊Aix⌋⇒S1≤S2

即按 A i A_i Ai 升序排序最优。

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[200001],ans,cnt;
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);     
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	sort(a+1,a+1+n);//升序排序
	cnt=a[1];
	for(int i=2;i<=n;i++)
		ans+=cnt/a[i],cnt+=a[i];//求负载
	cout<<ans;
	return 0;
}
相关推荐
Darkwanderor3 小时前
什么数据量适合用什么算法
c++·算法
超绝振刀怪3 小时前
【C++多态】
开发语言·c++
zc.ovo4 小时前
河北师范大学2026校赛题解(A,E,I)
c++·算法
py有趣4 小时前
力扣热门100题之环形链表
算法·leetcode·链表
py有趣4 小时前
力扣热门100题之回文链表
算法·leetcode·链表
学嵌入式的小杨同学5 小时前
STM32 进阶封神之路(三十九)FreeRTOS 临界区、挂起 / 删除、钩子函数、调度底层原理|从应用到内核深度解析
c++·stm32·单片机·嵌入式硬件·mcu·硬件架构·pcb
oioihoii5 小时前
Cursor根本无法调试C++
开发语言·c++
月落归舟6 小时前
帮你从算法的角度来认识二叉树---(二)
算法·二叉树
SilentSlot7 小时前
【数据结构】Hash
数据结构·算法·哈希算法