1 条题解
-
0
题解:The Trip, 2007(旅行行李嵌套问题)
一、题目分析
本题要求将多个尺寸不同的袋子进行嵌套打包,使得:
- 行李件数最少:即最外层袋子的数量最少,等价于每种尺寸的袋子中,出现次数最多的尺寸的出现次数(因为每个行李件只能包含一个该尺寸的袋子作为最外层)。
- 在行李件数最少的前提下,单个行李件中的袋子数量尽可能少:通过合理分配各尺寸袋子到不同的行李件中,使得每个行李件的袋子数量均匀分布。
二、核心思路
-
确定最少行李件数:
最少行李件数由出现次数最多的尺寸的袋子数量决定。例如,若某尺寸袋子出现了 ( u ) 次,则至少需要 ( u ) 个行李件(每个行李件的最外层只能是一个该尺寸的袋子)。 -
分配袋子到行李件:
- 首先对所有袋子的尺寸进行排序。
- 将排序后的袋子按行李件数 ( u ) 进行分组,每个行李件依次取第 ( i, i+u, i+2u, \dots ) 个袋子(( i ) 为行李件编号,从 0 到 ( u-1 ))。这样可以确保每个行李件内的袋子尺寸递增(因为排序后尺寸非递减),且每个行李件的袋子数量尽可能均衡,从而满足“单个行李件中的袋子数量最少”的要求。
三、代码解析
#include <iostream> #include <cstring> #include <algorithm> using namespace std; #define N 1000100 // 最大尺寸值+1 int c[N]; // 统计各尺寸的出现次数 int a[N]; // 存储所有袋子尺寸 int main() { int n; while (scanf("%d", &n) != EOF && n != 0) { memset(c, 0, sizeof(c)); // 初始化计数数组 int max_count = 0; // 记录最大出现次数(即最少行李件数) // 读取所有袋子尺寸并统计出现次数 for (int i = 0; i < n; i++) { scanf("%d", &a[i]); c[a[i]]++; if (c[a[i]] > max_count) { max_count = c[a[i]]; // 更新最大出现次数 } } // 对袋子尺寸进行排序(非递减顺序) sort(a, a + n); // 输出最少行李件数 printf("%d\n", max_count); // 分配袋子到各个行李件中 for (int i = 0; i < max_count; i++) { // 每个行李件的第一个元素为 a[i] printf("%d", a[i]); // 依次取间隔为 max_count 的元素,填充当前行李件 for (int j = i + max_count; j < n; j += max_count) { printf(" %d", a[j]); } printf("\n"); } // 测试用例之间输出空行(题目要求) static bool first_case = true; if (!first_case) { printf("\n"); } first_case = false; } return 0; }
四、步骤详解
-
输入处理与统计:
- 使用数组
c
统计每个尺寸的出现次数,同时记录最大出现次数max_count
,该值即为最少行李件数。
- 使用数组
-
排序:
- 对袋子尺寸进行排序,确保后续分配时每个行李件内的尺寸递增(满足嵌套条件)。
-
分配袋子到行李件:
- 每个行李件从索引
i
开始(i
从 0 到max_count-1
),依次取索引为i, i+max_count, i+2*max_count, ...
的袋子。 - 例如,当
max_count=3
,n=6
时,第一个行李件取a[0], a[3]
,第二个取a[1], a[4]
,第三个取a[2], a[5]
,确保每个行李件内的尺寸递增且数量均衡。
- 每个行李件从索引
-
输出格式处理:
- 每个测试用例之间需输出空行,通过静态变量
first_case
控制。
- 每个测试用例之间需输出空行,通过静态变量
五、关键点总结
- 最少行李件数的确定:由出现次数最多的尺寸决定,这是问题的核心约束。
- 贪心分配策略:排序后按间隔分配,确保每个行李件内的尺寸递增,且数量均衡,从而满足“单个行李件数量最少”的要求。
- 复杂度分析:排序的时间复杂度为 ( O(n \log n) ),适用于 ( n \leq 10000 ) 的数据规模。
该解法通过简单的统计和排序,高效地解决了嵌套打包问题,确保了最优解的两个条件同时满足。
- 1
信息
- ID
- 2288
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者