【问题标题】:Given a collection of stacks of different heights, how can I select every combination possible?给定一组不同高度的堆栈,我如何选择每个可能的组合?
【发布时间】:2012-01-26 00:54:09
【问题描述】:

输入:总成本。

输出:提供所需成本的所有级别组合。

每个堆栈的每一级花费不同的金额(堆栈 1 中的级别 1 与堆栈 2 中的级别 1 不同)。我有一个函数可以根据我手动输入的基本成本(级别 1)(硬编码)将级别转换为实际成本。

我需要找到能够为我提供输入成本的级别组合。我意识到有不止一种可能的解决方案,但我只需要一种方法来迭代每一种可能性。

这是我需要的:

input = 224,这是一个的解决方案:


我正在制作一个简单的程序,需要选择不同堆栈的级别然后计算成本,并且我需要知道存在的所有可能成本......每个堆栈的每个级别花费不同的金额,但是这不是问题,问题是如何为每个堆栈选择一个级别。

我可能解释得很含糊,所以这里有一张图片(你不得不原谅我的绘画技巧不佳):

所以,所有的堆栈都有 0 级,而 0 级总是花费 0 钱。

其他信息:

  • 我有一个名为“maxLevels”的数组,该数组的长度是堆栈数,每个元素是该堆栈中最高级别的编号(例如,maxLevels[0] == 2)。李>
  • 您可以从 1 级开始迭代,因为 0 级根本不重要。
  • 应将所选级别保存在与 maxLevels(相同长度)类似的数组(名称:“currentLevels”)中,但它不包含堆栈的最大级别,而是包含堆栈的所选级别(例如: currentLevels[3] == 2)。
  • 我正在使用 C++ 编程,但伪代码也可以。
  • 不是家庭作业,我是为了好玩(基本上是为了游戏)。

【问题讨论】:

  • 我已经重读了几次这个问题,但我很难理解它。您能否提供一个具体示例,显示输入、输出以及计算输出所采取的步骤?
  • 我不相信你会从中得到任何东西......只有输入是成本,每个堆栈的每个级别加起来一点,所以程序的任务是找到确切的不同级别的组合,因此它与成本相匹配。我马上回来,我会编辑问题!
  • ( currentLevels[0] + currentLevels[1] + currentLevels[2] + ... ) == requested_cost 这是你想要达到的目标吗?或者5级的成本可以和5级不同吗?
  • 我无法理解这一点,所以我倾向于投票结束,因为这不是一个真正的问题。但是,也许其他人会给出答案。看在上帝的份上,您能告诉我们问题是什么吗?
  • @bane 考虑到堆栈的当前配置和每个堆栈中每个项目的成本,您是否要求生成所有可能成本的算法?或者您是否要求给定一个成本值和给定堆栈配置的算法,并且每个项目的成本将产生生成给定成本值的堆栈选择?

标签: c++ arrays algorithm stack


【解决方案1】:

我不确定我是否理解这个问题,但这里是如何从每个堆栈中选择一个项目的所有可能组合(在本例中为 3*1*2*3*1 = 18 种可能性):

void visit_each_combination(size_t *maxLevels, size_t num_of_stacks, Visitor &visitor, std::vector<size_t> &choices_so_far) {
    if (num_of_stacks == 0) {
        visitor.visit(choices_so_far);
    } else {
        for (size_t pos = 0; pos <= maxLevels[0]; ++pos) {
            choices_so_far.push_back(pos);
            visit_each_combination(maxLevels+1, num_of_stacks-1, visitor, choices_so_far);
            choices_so_far.pop_back();
        }
    }
}

您可以将visitor.visit 替换为您想对每个组合执行的任何操作,以使代码更具体。我使用了向量 choices_so_far 而不是您的数组 currentLevels,但它也可以与数组一起使用。

【讨论】:

  • 嘿,我对 C++ 很陌生,你能用伪代码重新编码吗? size_t 是什么意思?星号和“&”符号是什么?我想与指针有关吗?我认为它可以做得更简单......到底什么是“访客”?一个东西?我完全迷失在“std::vector &choices_so_far”... 另外:“maxLevels+1”,这不是一个数组吗?怎么给数组加 1?
  • 嘿,我想我明白了。从本质上讲,我的解决方案与您的解决方案相似,因为我也使用了递归,所以我接受了您的回答,因为您有我的想法。谢谢。
【解决方案2】:

如果我理解正确的话,这很简单。最小成本为 0,最大成本只是堆栈高度的总和。要实现这些限制之间的任何特定成本,您可以从左侧开始,为每个堆栈选择最大级别,直到达到您的目标,然后为剩余的堆栈选择级别 0。 (如果超出目标,您可能需要调整最后一个非零堆栈。)

【讨论】:

  • 不,事实并非如此。确切的成本是不同堆栈的不同级别的组合。请看新图。 :)
  • 好吧,在这种情况下,您的问题是 NP 完全的,因为如果每个堆栈的高度为 2,它会简化为背包问题。这在实践中意味着如果数字堆栈的数量大于大约 30 或 40 - 请参阅 en.wikipedia.org/wiki/NP-complete
  • 我不会有任何问题。正如我所说,它是针对游戏的,其目标是计算某些玩家拥有哪些研究。游戏中有16个研究,因此我使用了16个堆栈。每个研究都有一个级别,每个级别的成本是前一个级别的两倍,第一个是该研究的基础成本。我想,我想通了,虽然它运行得不好(但不是这部分,我确实选择了所有可能性)。弄明白后,我迅速在世界积分排名第一的选手身上进行了测试,几秒钟就给出了结果。
【解决方案3】:

我想我解决了。 @Steve Jessop 给了我使用递归的想法。

算法:

circ(currentStack)
{
    for (i = 0; i <= allStacks[currentStack]; i ++)           
       if (currentStack == lastStack && i == allStacks[currentStack])
           return 0;
       else if (currentStack != lastStack)
           circ(++ currentStack);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    相关资源
    最近更新 更多