- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我经常教授大型入门编程类(class)(400 - 600 名学生),当考试时间临近时,我们通常不得不将类(class)分成不同的房间,以确保每个人都有座位参加考试。
为了在逻辑上保持简单,我通常按姓氏将类(class)分开。例如,我可能会将姓氏 A - H 的学生送到一个房间,将姓氏 I - L 送到第二个房间,将姓氏 M - S 送到第三个房间,将姓氏 T - Z 送到第四个房间。
这样做的挑战在于,房间的容纳人数通常大相径庭,而且很难找到一种让每个人都能适应的方式来划分类(class)。例如,假设姓氏的分布(为简单起见)如下:
假设我有容量为 350、50 和 50 的房间。用于查找房间分配的贪婪算法可能是将房间按容量降序排列,然后尝试按该顺序填充房间。不幸的是,这并不总是有效。例如,在这种情况下,正确的选择是将姓氏 A 放入一个大小为 50 的房间,将姓氏 B - C 放入大小为 350 的房间,将姓氏 D 放入另一个大小为 50 的房间。贪心算法将将姓氏 A 和 B 放入 350 人的房间,然后无法为其他人找到座位。
只需尝试房间排序的所有可能排列,然后对每个排序运行贪心算法,即可轻松解决此问题。这将找到有效的分配或报告不存在。但是,考虑到房间数量可能在 10 到 20 之间并且检查所有排列可能不可行,我想知道是否有更有效的方法来执行此操作。
总而言之,正式的问题陈述如下:
You are given a frequency histogram of the last names of the students in a class, along with a list of rooms and their capacities. Your goal is to divvy up the students by the first letter of their last name so that each room is assigned a contiguous block of letters and does not exceed its capacity.
是否有一个有效的算法,或者至少有一个对合理的房间大小有效的算法?
编辑:很多人都问过连续条件。规则是
例如,您不能将 A - E、H - N 和 P - Z 放入同一个房间。您也不能将 A - C 放在一个房间,而将 B - D 放在另一个房间。
谢谢!
最佳答案
可以在 [m, 2^n]
空间上使用某种 DP 解决方案来解决,其中 m
是字母数(英语为 26)并且 n
是房间数。使用 m == 26
和 n == 20
它将占用大约 100 MB 的空间和大约 1 秒的时间。下面是我刚刚用 C# 实现的解决方案(它也可以在 C++ 和 Java 上成功编译,只需要做一些小的改动):
int[] GetAssignments(int[] studentsPerLetter, int[] rooms)
{
int numberOfRooms = rooms.Length;
int numberOfLetters = studentsPerLetter.Length;
int roomSets = 1 << numberOfRooms; // 2 ^ (number of rooms)
int[,] map = new int[numberOfLetters + 1, roomSets];
for (int i = 0; i <= numberOfLetters; i++)
for (int j = 0; j < roomSets; j++)
map[i, j] = -2;
map[0, 0] = -1; // starting condition
for (int i = 0; i < numberOfLetters; i++)
for (int j = 0; j < roomSets; j++)
if (map[i, j] > -2)
{
for (int k = 0; k < numberOfRooms; k++)
if ((j & (1 << k)) == 0)
{
// this room is empty yet.
int roomCapacity = rooms[k];
int t = i;
for (; t < numberOfLetters && roomCapacity >= studentsPerLetter[t]; t++)
roomCapacity -= studentsPerLetter[t];
// marking next state as good, also specifying index of just occupied room
// - it will help to construct solution backwards.
map[t, j | (1 << k)] = k;
}
}
// Constructing solution.
int[] res = new int[numberOfLetters];
int lastIndex = numberOfLetters - 1;
for (int j = 0; j < roomSets; j++)
{
int roomMask = j;
while (map[lastIndex + 1, roomMask] > -1)
{
int lastRoom = map[lastIndex + 1, roomMask];
int roomCapacity = rooms[lastRoom];
for (; lastIndex >= 0 && roomCapacity >= studentsPerLetter[lastIndex]; lastIndex--)
{
res[lastIndex] = lastRoom;
roomCapacity -= studentsPerLetter[lastIndex];
}
roomMask ^= 1 << lastRoom; // Remove last room from set.
j = roomSets; // Over outer loop.
}
}
return lastIndex > -1 ? null : res;
}
来自 OP 问题的示例:
int[] studentsPerLetter = { 25, 150, 200, 50 };
int[] rooms = { 350, 50, 50 };
int[] ans = GetAssignments(studentsPerLetter, rooms);
答案是:
2
0
0
1
其中表示每个学生姓氏字母的空间索引。如果无法分配,我的解决方案将返回 null
。
[编辑]
经过数千次自动生成的测试后,我的 friend 在代码中发现了一个向后构造解决方案的错误。它不影响主要算法,因此修复此错误将成为读者的练习。
揭示错误的测试用例是 students = [13,75,21,49,3,12,27,7]
和 rooms = [6,82,89, 6,56]
。我的解决方案没有返回任何答案,但实际上有一个答案。请注意,解决方案的第一部分工作正常,但答案构建部分失败。
关于algorithm - 按姓氏将人们分配到房间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16377079/
我有一个应用程序,它会抛出 GKSession 并在各种条件下(连接超时、 session 失败等)创建一个新的 GKSession。不过,我遇到了内存泄漏问题,并且有时会在重新连接几次循环后崩溃。
比如我在宿主代码中有一个浮点指针 float *p 是否可以确定他指向的内存类型(设备/主机)? 最佳答案 在 UVA system 中, 运行时 API 函数 cudaPointerGetAttri
我已将项目转换为 .Net 4.0 并且以下代码不起作用: typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Instance
当我声明 char ch = 'ab' 时,ch 只包含 'b',为什么它不存储 'a'? #include int main() { char ch = 'ab'; printf("%c"
我对 Disk Sector 和 Block 有疑问。扇区是一个单位,通常为 512 字节或 1k、2k、4k 等取决于硬件。文件系统 block 大小是一组扇区大小。 假设我正在存储一个 5KB 的
假设我有 8 个人和5000 个苹果。 我想将所有苹果分发给所有 8 个人,这样我就没有苹果了。 但每个人都应该得到不同数量 将它们全部分发出去的最佳方式是什么? 我是这样开始的: let peopl
我正在构建的网站顶部有一个搜索栏。与 Trello 或 Gmail 类似,我希望当用户按下“/”键时,他们的焦点就会转到该搜索框。 我的 JavaScript 看起来像这样: document.onk
我有一小段代码: if (PZ_APP.dom.isAnyDomElement($textInputs)){ $textInputs.on("focus", function(){
我观察到以下行为。 接受了两个属性变量。 @property (nonatomic, retain) NSString *stringOne; @property (nonatomic, assign
我正在解决这样的问题 - 实现一个计算由以下内容组成的表达式的函数以下操作数:“(”、“)”、“+”、“-”、“*”、“/”。中的每个数字表达式可能很大(与由字符串表示的一样大)1000 位)。 “/
我有一组主机和一组任务。 每个主机都有 cpu、mem 和任务容量,每个任务都有 cpu、mem 要求。 每个主机都属于一个延迟类别,并且可以与具有特定延迟值的其他主机通信。 每个任务可能需要以等于或
该程序的作用:从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。矩阵的所有元素都是 [0,100) 之间的整数。程序必须重新排列矩阵内的所有元素,使每个元素等于其所在
世界!我有个问题。今天我尝试创建一个代码,它可以找到加泰罗尼亚语号码。但是在我的程序中可以是长数字。我找到了分子和分母。但我不能分割长数字!此外,只有标准库必须在此程序中使用。请帮帮我。这是我的代码
我确定我遗漏了一些明显的东西,但我想在 Objective C 中创建一个 NSInteger 指针的实例。 -(NSInteger*) getIntegerPointer{ NSInteger
这个问题在这里已经有了答案: Difference between self.ivar and ivar? (4 个答案) 关闭 9 年前。
我如何将 v[i] 分配给一系列整数(v 的类型是 vector )而无需最初填充 最佳答案 你的意思是将 std::vector 初始化为一系列整数? int i[] = {1, 2, 3, 4,
我想寻求分配方面的帮助....我把这个作业带到了学校......我必须编写程序来加载一个 G 矩阵和第二个 G 矩阵,并搜索第二个 G 矩阵以获取存在数第一个 G 矩阵的......但是,当我尝试运行
我必须管理资源。它基本上是一个唯一的编号,用于标识交换机中的第 2 层连接。可以有 16k 个这样的连接,因此每次用户希望配置连接时,他/她都需要分配一个唯一索引。同样,当用户希望删除连接时,资源(号
是否有任何通用的命名约定来区分已分配和未分配的字符串?我正在寻找的是希望类似于 us/s 来自 Making Wrong Code Look Wrong ,但我宁愿使用常见的东西也不愿自己动手。 最佳
我需要读取一个 .txt 文件并将文件中的每个单词分配到一个结构中,该结构从结构 vector 指向。我将在下面更好地解释。 感谢您的帮助。 我的程序只分配文件的第一个字... 我知道问题出在函数 i
我是一名优秀的程序员,十分优秀!