对于给定的N,[1,2,3,...,N]的多少个排列满足以下属性。
设P1,P2,...,PN表示置换。我们想要满足的属性是存在2和n-1(包括)之间的i,使得
Pj> Pj +1∀i≤j≤N - 1。
Pj> Pj - 1∀2≤j≤i。
喜欢N = 3
Permutations [1, 3, 2] and [2, 3, 1] satisfy the property.
是否有任何直接的公式或算法可以在编程中找到这些设置。
答案 0 :(得分:2)
有2^(n-1) - 2
个这样的排列。如果n
是最大的元素,则排列由{1, 2, ..., n-1}
的非空的适当子集唯一确定,该子集位于排列中n
的左侧。这个答案与@גלעדברקן的优秀答案是一致的,因为众所周知的事实是Pascal三角形的每一行中的元素总和为2的幂(因此两者之间的行的部分比两个人的力量。)
这是一个生成所有n的Python枚举!排列并检查它们的有效性:
import itertools
def validPerm(p):
n = max(p)
i = p.index(n)
if i == 0 or i == n-1:
return False
else:
before = p[:i]
after = p[i+1:]
return before == sorted(before) and after == sorted(after, reverse = True)
def validPerms(n):
nums = list(range(1,n+1))
valids = []
for p in itertools.permutations(nums):
lp = list(p)
if validPerm(lp): valids.append(lp)
return valids
例如,
>>> validPerms(4)
[[1, 2, 4, 3], [1, 3, 4, 2], [1, 4, 3, 2], [2, 3, 4, 1], [2, 4, 3, 1], [3, 4, 2, 1]]
给出预期的数字6。
进一步编辑:以上代码用于验证非退化单峰排列的公式(用于拼写短语,因为“单峰排列”用于2^(n-1)
排列的文献中恰好是一个峰值,但以n
开头或结尾的2可以说在某种意义上是退化的。从枚举的角度来看,您可能希望做更有效的事情。以下是@גלעדברקן:
def validPerms(n):
valids = []
nums = list(range(1,n)) #1,2,...,n-1
snums = set(nums)
for i in range(1,n-1):
for first in itertools.combinations(nums,i):
#first will be already sorted
rest = sorted(snums - set(first),reverse = True)
valids.append(list(first) + [n] + rest)
return valids
它在功能上等同于上面的代码,但效率更高。
答案 1 :(得分:1)
让我们看一个例子:
{1,2,3,4,5,6}
显然,6
在i
处的任何定位都意味着它的右侧将按降序排序,而其左侧将按升序排序。例如,i = 3
{1,2,6,5,4,3}
{1,3,6,5,4,2}
{1,4,6,5,3,2}
...
因此N
与2
之间n-1
的每个定位都有(n - 1) choose (position - 1)
个排列。这导致了答案:
sum [(n - 1) choose (i - 1)], for i = 2...(n - 1)
答案 2 :(得分:-1)
有ans烫发。和ans如下
ans等于2 ^(n-1)和 ans - = 2 因为它需要在2< = i< = n-1&&我们知道nC1和nCn = 1