解决2010年ACM问题:城堡

时间:2010-02-18 02:17:41

标签: algorithm

发布您最好的解决方案!您可以在此处找到完整的问题说明和示例:ACM 2010 problems (pdf)

你有一组通过道路连接的城堡,你想用最少的士兵征服所有的城堡。每座城堡都有三个属性:需要最少的士兵数量,将要死亡的士兵数量,以及必须留下的士兵数量。

任何两座城堡之间只有一条路(道路形成一棵树)。您可以选择任何城堡作为第一个目标,但您必须遵循道路。你只能两次旅行。你的流动军队必须留在一个小组内。

3 个答案:

答案 0 :(得分:1)

我会这样解决这个问题:

Bruteforce所有起始城堡(最多100个) 对于每个起始城堡: 填满数组

需要[i]和成本[i]意味着当你从选择的起点到i,并试图从i开始确认子树时,你至少需要[i]焊料和成本[i]焊料将死。

min_solder_to_attack_castle [i]来自输入文件。

显然,对于“终端”城堡来说,需要[]和成本[]值是显而易见的。 然后,对于所有已知需要[]和所有“孩子”费用[]值的城堡,您可以通过这种方式计算这座城堡的需求和成本:

费用[i] =总和(费用[孩子])

需要[i]是棘手的部分:我们知道它介于max(min_solder_to_attack_castle [all childs])和max(min_solder_to_attack_castle [all childs])+ max(cost [all childs])之间。尝试所有变种将花费我们(number_of_childs)!并且可能是n!,可能优化会有所帮助,这里是我现在停下来的地方。

答案 1 :(得分:0)

我会反过来解决这个问题 - 你希望在尽可能地占用最后一座城堡之后,“浪费”少数男人“浪费”。由于我们不能不经过城堡,我们显然会在一个“叶子”城堡结束。

直接从所有叶子城堡向后走,以确定每个子树上“浪费”的人数总数 - 然后只是按照正确的顺序行走子树。

小学,亲爱的沃森。

答案 2 :(得分:0)

首先要意识到的是,就数字而言,失去的士兵和留下的士兵之间没有区别。因此,我们可以将城堡属性减少到失去和需要的士兵。

要意识到的第二件事是,如果你沿着树的一个分支走下去,你必须完成整个分支的返回。这使我们能够将整个分支机构减少为一个“大城堡”,需要和失去聚合士兵。

因此,假设我们可以计算分支的成本,我们就会遇到两个问题:从哪里开始,以及如何选择首先下降的分支。我只是强迫开始的位置,但它可能会做得更好。选择要下降的分支有点难度。失去的士兵数量是微不足道的,但所需数量不是。有n!可能性,所以我们不能只尝试所有。

我没有考虑每座城堡丢失/需要多少士兵,而是要倒退。从0名士兵开始,并在攻击城堡时添加它们,确保我们至少达到所需数量。有两种情况:要么有一座我们符合要求的城堡,要么没有。如果有,(联合国)做那个城堡(这是最佳的,因为我们使用了最少数量的士兵)。如果没有,请添加一名士兵并再试一次(这是最佳选择,因为我们必须添加士兵才能继续)。现在它应该变得显而易见:我们希望(联合国)城堡的要求最接近首先丢失的数字。只需排序(必需减去),这就是你的订单。

所以最终算法看起来像这样:

  • 蛮力起点
  • 递归地将分支缩减为聚合城堡(记住此结果,对于其他起点)
  • 按降序(必修减去)顺序访问分支机构。

运行时间为O(n * c ^ 2 * lg(c)),其中n是城堡的数量,c是任何单个城堡的最大连通性。这更糟糕,因为最多有n个 c'个分支',并且一个节点在评估其分支之后最多需要c lg(c)时间进行评估。 [由于记忆的原因,分支和节点最多计算一次]

我认为可以做得更好,但我不确定如何。