Math 我们需要按什么顺序在秤上称重?
我正在做编程方面的作业,我不知道如何解决这个问题: 我们有一组n个权重,我们把它们一个一个地放在秤上,直到所有的权重都被使用。我们还有n个字母“R”或“L”的字符串,这意味着哪支笔在那一刻更重,它们不能平衡。没有具有相同质量的砝码。计算重量在天平上的顺序以及在哪个平底锅上 我们的目标是找到在标尺上放置权重的顺序,这样就可以考虑输入字符串 输入:数字0Math 我们需要按什么顺序在秤上称重?,math,combinatorics,Math,Combinatorics,我正在做编程方面的作业,我不知道如何解决这个问题: 我们有一组n个权重,我们把它们一个一个地放在秤上,直到所有的权重都被使用。我们还有n个字母“R”或“L”的字符串,这意味着哪支笔在那一刻更重,它们不能平衡。没有具有相同质量的砝码。计算重量在天平上的顺序以及在哪个平底锅上 我们的目标是找到在标尺上放置权重的顺序,这样就可以考虑输入字符串 输入:数字0
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字符串尚未使用
- 平底锅上砝码的当前状态,其格式在定稿时可以轻松打印(可能是砝码和平底锅的有序配对数组)
- 锅的当前重量不平衡。这可以从前面的参数计算出来,但是单独传递这个参数可以节省时间。这将是右盘上的总重量减去左盘上的总重量(反之亦然)
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