- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
你得到了N个高度为1…N的块。你可以用多少种方法将这些块排列成一行,这样当你从左边看时,你只看到L个块(其余的块被更高的块隐藏),当你从右边看时,你只看到R个块举例来说,N=3, L=2, R=1
只有一种排列方式,{2, 1, 3}
有两种方式。
我们应该如何通过编程来解决这个问题有什么有效的方法吗?
最佳答案
这是一个计数问题,而不是构造问题,所以我们可以使用递归来处理它因为问题有两个自然的部分,从左边看和从右边看,所以先把它分解,只解决一个部分。
设b(N, L, R)
为解的数目,设f(N, L)
为N
块的排列数目,以便L
从左侧可见首先考虑f
因为它更容易。
方法1
我们先得到初始条件,然后进行递归。如果所有这些都是可见的,那么它们必须越来越多地被订购,所以
f(N, N) = 1
f(N, M) = 0 if N < M
f(N,1) = (N-1)!
N
位于左侧的
k
第th个点然后以
(N-1 choose k-1)
的方式选择要在其前面的块,排列这些块,以便从左侧可以看到
L-1
,并按您喜欢的方式对
N-k
后面的
N
块排序,给出:
f(N, L) = sum_{1<=k<=N} (N-1 choose k-1) * f(k-1, L-1) * (N-k)!
f(x-1,L-1) = 0
表示
x<L
,我们最好在
k
开始
L
,而不是
1
:
f(N, L) = sum_{L<=k<=N} (N-1 choose k-1) * f(k-1, L-1) * (N-k)!
f
来求解更难的位
b
再次,根据最高块的位置使用递归,再次声明
N
位于左侧的
k
位置和以前一样,以
N-1 choose k-1
方式选择前面的块,但现在分别考虑该块的每一侧对于
k-1
左侧的
N
块,确保它们的
L-1
完全可见对于
N-k
右侧的
N
块,确保
R-1
可见,然后反转从
f
获得的顺序。因此,答案是:
b(N,L,R) = sum_{1<=k<=N} (N-1 choose k-1) * f(k-1, L-1) * f(N-k, R-1)
f
完全在上面计算出来。同样,许多项都是零,所以我们只想取
k
这样
k-1 >= L-1
和
N-k >= R-1
就可以得到
b(N,L,R) = sum_{L <= k <= N-R+1} (N-1 choose k-1) * f(k-1, L-1) * f(N-k, R-1)
f
的递归将变得简单得多在这种情况下,在相同的初始条件下,递归是
f(N,L) = f(N-1,L-1) + (N-1) * f(N-1,L)
f(N-1,L-1)
来自于将最小块放置在最左边的位置,从而添加另一个可见块(因此
L
减少到
L-1
),第二项
(N-1) * f(N-1,L)
用于将最小块放置在任何
N-1
非前位置,在这种情况下,它不可见(因此
L
保持固定)。
N
,尽管它使某些公式更难看到,例如
f(N,N-1) = (N choose 2)
这个公式很容易从前面的公式中显示出来,尽管我不确定如何从这个简单的递归中很好地导出它。
b
,我们也可以采取不同的方法与前面的求和不同的是,把可见的块看作是包中的块,这样如果一个块从左边可见,那么它的包由它右边的所有块和从左边可见的下一个块前面组成,同样,如果一个块从右边可见,那么它的包包含它左边的所有块,直到下一个块从右边可见为止。除了最高的街区,其他的都要这样做。这就产生了
L+R
包。给定数据包,只需颠倒块的顺序,就可以将数据包从左侧移到右侧因此,一般情况下
b(N,L,R)
实际上减少到解决情况
b(N,L,1) = f(N,L)
然后选择哪些包放在左边,哪些放在右边。因此我们有
b(N,L,R) = (L+R choose L) * f(N,L+R)
f(N,L)
数字正是(无符号的)
Stirling numbers of the first kind。从每个函数的递归公式中可以立即看到这一点。但是,能够直接看到它总是很好的,所以这里。
S(N,L)
将
N
的置换数计数为
L
个循环给定一个用循环表示法写的置换,我们以规范形式写置换,方法是用该循环中最大的数开始循环,然后按循环的第一个数逐渐对循环进行排序例如,置换
(2 6) (5 1 4) (3 7)
(5 1 4) (6 2) (7 3)
关于algorithm - Google面试: block 的排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28057057/
我需要在给定的列表上生成排列。我设法这样做 let rec Permute (final, arr) = if List.length arr > 0 then for x i
我正在尝试运行我的代码,以便它打印循环排列,尽管我目前只能让它执行第一个排列。它正确运行到我标记的点,但我看不出出了什么问题。我认为 while 循环中没有中断,但我不确定。确实需要一些帮助。 pac
我正在尝试计算不包含连续字母的排列数。我的代码通过了像“aabb”(答案:8)和“aab”(答案:2)这样的测试,但没有通过像“abcdefa”这样的情况(我的答案:2520;正确答案:3600)。这
我正在尝试使用 dplyr 的 arrange 根据条件对字符串进行排序。我想在一列上排列,但如果第二列等于一个值,则按升序排列,如果第二列等于另一个值,则按降序排列。 我发现了几个类似的问题(其中一
在 R 中,我使用 dplyr更具体地说 arrange() . 不知何故 arrange功能没有按预期工作。 在下面的示例中,我首先存储列的名称,然后将此变量作为参数传递给名为“my_functio
以下是我的 main.qml : Window { id: window visible: true width: 800 height: 480 title:
很难用谷歌搜索这个问题,因为我不确定这些概念叫什么,并且所有“两个数组/组的组合”SO 帖子都没有给我我期望的输出。 数组示例: var array1 = ['Bob', 'Tina']; var a
实现以下目标的最佳方法是什么?我有两个列表: val l1 = List("a", "b") val l2 = List(1, 2) 我想生成这个: List ( List(('a', 1)
我知道互联网上有很多针对我的具体问题的解决方案,但我一直在尝试以特定的方式解决它,但它不起作用,我真的无法理解出了什么问题。就我而言,我只想打印排列。这是我的代码: a = "abc"; functi
我有这样的代码来创建排列: --unique permutation perm :: [t] -> [[t]] perm [] = [[]] perm (x:xs) = [(y:zs) | (y,ys
有没有比使用基本公式 n!/(n-r)! 更好的方法?就像我们对 nCr(组合) nCr = (n-l)Cr + (n-1)C(r-1) 一样? 最佳答案 这样怎么样:nPr = (n−1)Pr +
此问答的动机是 How to build permutation with some conditions in R . 到目前为止,已经有一些很好的 R 软件包,例如 RcppAlgos 和 arr
我正在修改一本书中的排列示例。以下代码按预期工作。 perms([]) -> [[]]; perms(L) -> [[H|T] || H []; 它返回一个空列表。当我替换时,我得到了这个。
大约一周前,我问了一个关于帮助我解决这个问题的问题 Java permutations ,打印排列方法有问题。我已经整理了我的代码,并有一个现在可以工作的工作示例,尽管如果 5 位于数组中的第五个位置
我有一个包含重复元素的列表,即orig = [1,1,1,2,2,3]。 我想创建一个derangement b = f(orig),使得 b 中的每个位置值都与 orig 中的值不同: b[i] !
我想生成一个 array a 的排列而且我不想使用实用功能,例如 java.util.Collections() . 排列应该是随机的,并且每个排列都应该有可能发生 - 但不需要均等分布的概率。 以下
我有一个作业:用户输入一个字符串,例如 ABCD,程序必须给出所有排列。我不希望整个代码只是一个提示。这是我到目前为止在他们那里得到的,我没有得到任何实现。 以ABCD为例: 在本例中获取字符串长度的
我目前正在编写一个使用 itertools 的程序,其中的一部分似乎无法正常运行。我希望确定排列函数输出列表长度的输入等于它生成输出的列表长度。换句话说,我有 import itertools b =
我有一个列表 x=[1,2,3,4,5] 并且想查看这个列表的不同排列,一次取两个数字。 x=[1,2,3,4,5] from itertools import permutations y=list
我正在寻找 C 或 Python 代码来实现两个伪代码函数之一: function 1: list1 = [0,1,2] #any list of single-integer elements li
我是一名优秀的程序员,十分优秀!