Math 我们需要按什么顺序在秤上称重?

Math 我们需要按什么顺序在秤上称重?,math,combinatorics,Math,Combinatorics,我正在做编程方面的作业,我不知道如何解决这个问题: 我们有一组n个权重,我们把它们一个一个地放在秤上,直到所有的权重都被使用。我们还有n个字母“R”或“L”的字符串,这意味着哪支笔在那一刻更重,它们不能平衡。没有具有相同质量的砝码。计算重量在天平上的顺序以及在哪个平底锅上 我们的目标是找到在标尺上放置权重的顺序,这样就可以考虑输入字符串 输入:数字0

我正在做编程方面的作业,我不知道如何解决这个问题:

我们有一组n个权重,我们把它们一个一个地放在秤上,直到所有的权重都被使用。我们还有n个字母“R”或“L”的字符串,这意味着哪支笔在那一刻更重,它们不能平衡。没有具有相同质量的砝码。计算重量在天平上的顺序以及在哪个平底锅上

我们的目标是找到在标尺上放置权重的顺序,这样就可以考虑输入字符串

输入:数字0 输出:在n行,重量和“R”或“L”,你们放重量的一边。如果有多个,则输出其中任何一个

例1:

输入:

3
10 20 30
LRL
3
10 20 30
LLR
5
10 20 30 40 50
LLLLR
输出:

10 L
20 R
30 L
20 L
10 R
30 R
50 L
10 L
20 R
30 R
40 R
例2:

输入:

3
10 20 30
LRL
3
10 20 30
LLR
5
10 20 30 40 50
LLLLR
输出:

10 L
20 R
30 L
20 L
10 R
30 R
50 L
10 L
20 R
30 R
40 R
例3:

输入:

3
10 20 30
LRL
3
10 20 30
LLR
5
10 20 30 40 50
LLLLR
输出:

10 L
20 R
30 L
20 L
10 R
30 R
50 L
10 L
20 R
30 R
40 R

我已经尝试过用递归计算它,但没有成功。有人能帮我解决这个问题吗?或者只是给我一些提示如何解决它

既然您没有显示自己的任何代码,我就给您一些没有代码的想法。如果您需要更多帮助,请展示更多的工作,然后我可以向您展示解决问题的Python代码

你的问题适合我。维基百科对此算法的定义是

回溯是一种通用算法,用于查找某些解决方案的所有(或某些)解决方案,尤其是增量地为解决方案构建候选方案,并在确定候选方案不可能完成为有效解决方案时放弃候选方案(“回溯”)

回溯只能应用于承认“部分候选解决方案”概念的问题,以及一个相对快速的测试,测试它是否可能完成为一个有效的解决方案

您的问题满足这些要求。在每个阶段,你需要选择一个剩余的砝码和两个天平中的一个。将所选权重放置在所选平移上时,确定是否满足输入字符串中的相应字母。如果没有,则拒绝选择重量和平底锅。如果是这样,请继续选择另一个砝码和平底锅

您的整个例行程序首先输入和准备数据。然后它调用一个递归例程,在每个级别选择一个权重和一个平移。每个级别所需的一些信息可以放入可变的全局变量中,但如果您将所有需要的信息作为参数传递,则会更加清楚。对递归例程的每次调用都需要传递:

  • 尚未使用的砝码
  • 输入的L/R字符串尚未使用
  • 平底锅上砝码的当前状态,其格式在定稿时可以轻松打印(可能是砝码和平底锅的有序配对数组)
  • 锅的当前重量不平衡。这可以从前面的参数计算出来,但是单独传递这个参数可以节省时间。这将是右盘上的总重量减去左盘上的总重量(反之亦然)
递归的基本情况是未使用的权重和未使用的字母为空。然后,您已完成搜索,可以打印解决方案并退出程序。否则,将循环使用一个未使用的砝码和一个平底锅的所有组合。对于每种组合,计算如果你把重量放在锅上,新的不平衡会是什么。如果新的不平衡与相应的字母一致,则使用适当修改的参数递归调用例程。如果没有,不要对这个重量和平底锅进行任何操作

在编码之前,您仍然有一些选择要做,例如未使用权重的数据结构。让我看看你自己的一些编码工作,然后我会给你我的Python代码

请注意,对于大量重量,这可能会很慢。对于
n
砝码和两个平底锅,在平底锅上放置砝码的方法总数为
n!*2**n
(即阶乘和幂运算)。对于超过
3e79
n=50
,太大了。回溯避免了大多数选择组,因为选择会尽快被拒绝,但我的算法可能仍然很慢。也许有比回溯更好的算法,但我看不到。您的问题似乎被设计为通过回溯来处理


现在您已经展示了自己的更多努力,下面是我未优化的Python 3代码。这适用于您给出的所有示例,尽管我为您的第三个示例提供了不同的有效解决方案

def weights_on_pans():
    def solve(unused_weights, unused_tilts, placement, imbalance):
        """Place the weights on the scales using recursive
        backtracking. Return True if successful, False otherwise."""
        if not unused_weights:
            # Done: print the placement and note that we succeeded
            for weight, pan in placement:
                print(weight, 'L' if pan < 0 else 'R')
            return True  # success right now
        tilt, *later_tilts = unused_tilts
        for weight in unused_weights:
            for pan in (-1, 1):  # -1 means left, 1 means right
                new_imbalance = imbalance + pan * weight
                if new_imbalance * tilt > 0:  # both negative or both positive
                    # Continue searching since imbalance in proper direction
                    if solve(unused_weights - {weight},
                             later_tilts,
                             placement + [(weight, pan)],
                             new_imbalance):
                        return True  # success at a lower level
        return False  # not yet successful

    # Get the inputs from standard input. (This version has no validity checks)
    cnt_weights = int(input())
    weights = {int(item) for item in input().split()}
    letters = input()
    # Call the recursive routine with appropriate starting parameters.
    tilts = [(-1 if letter == 'L' else 1) for letter in letters]
    solve(weights, tilts, [], 0)

weights_on_pans()
def weights_on_pans():
def solve(未使用的重量、未使用的倾斜、放置、不平衡):
“”“使用递归方法将砝码放在秤上
回溯。如果成功返回True,否则返回False。”“”
如果不是未使用的重量:
#完成:打印位置并注意我们成功了
对于重量,在放置时平移:
打印(如果pan<0,则重量为“L”,否则为“R”)
立即返回真正的成功
倾斜,*以后倾斜=未使用的倾斜
对于未使用的_重量中的重量:
对于平移输入(-1,1):#-1表示左,1表示右
新的不平衡=不平衡+盘*重量
如果新的不平衡*倾斜>0:#均为负值或均为正值
#继续搜索,因为方向正确
如果求解(未使用的_权重-{weight}),
后来,,
位置+[(重量,盘)],
新的(不平衡):
返回真实#较低级别的成功
返回False#尚未成功
#从标准输入获取输入。(此版本没有有效性检查)
cnt_weights=int(输入())
权重={int(项)用于输入()中的项。拆分()}
字母=输入()
#调用递归例程wi