Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 锯齿序列计数_Python_Dynamic Programming_Combinatorics - Fatal编程技术网

Python 锯齿序列计数

Python 锯齿序列计数,python,dynamic-programming,combinatorics,Python,Dynamic Programming,Combinatorics,Z字形序列是一种序列,其中每个元素都小于或大于其相邻元素:1 3 2和2 1 2是Z字形,1 2 3和1 2不是Z字形 给定两个数字n,k找出从数字1..k可以生成多少个大小为n的序列 示例:n=3 k=3答案:10 121、212、131、313、232、323、132、231、312、213(为了清楚起见,不需要生成) 我找到了这个解决方案。请告诉我是否可以做得更好 import sys ZAG = {} ZIG = {} def zag(n, i): result = 0

Z字形序列是一种序列,其中每个元素都小于或大于其相邻元素:
1 3 2
2 1 2
是Z字形,
1 2 3
1 2
不是Z字形

给定两个数字n,k找出从数字1..k可以生成多少个大小为n的序列

示例:n=3 k=3答案:10

121、212、131、313、232、323、132、231、312、213(为了清楚起见,不需要生成)

我找到了这个解决方案。请告诉我是否可以做得更好

import sys

ZAG = {}
ZIG = {}

def zag(n, i):
    result = 0

    for j in xrange(1, i):    
        if (n - 1, j) not in ZIG:
            ZIG[(n - 1, j)] = zig(n - 1, j)
        result += ZIG[(n - 1, j)]

    return result    

def zig(n, i):
    result = 0

    for j in xrange(i + 1, MAX_NUMBER + 1):
        if (n - 1, j) not in ZAG:
            ZAG[(n - 1, j)] = zag(n - 1, j)
        result += ZAG[(n - 1, j)]

    return result

def count(n): 
    if n == 1:
        return MAX_NUMBER

    result = 0

    for i in xrange(1, MAX_NUMBER + 1):
        ZIG[(1, i)] = 1
        ZAG[(1, i)] = 1

    for i in xrange(1, MAX_NUMBER + 1):
        result += 2*zag(n, i)

    return result

def main(argv):
    global MAX_NUMBER
    MAX_NUMBER = int(argv[1])
    print count(int(argv[0]))

if __name__ == "__main__":
    main(sys.argv[1:])

如果通过递归调用Zig(值小于最后一个数)和Zag(值大于最后一个数)迭代各种可能性来生成序列,它会变得更好一些,而且可以做得更好(计算方面,而不是内存方面)通过将已解决的子问题存储在静态表中。

整个序列中的顺序由前两个元素的顺序给出。有两种订购方式:上下向上。。。和上下-。。。两种排序的序列数量相同,因为一种排序的序列可以通过将每个编号
x
k+1-x
交换而转换为另一种排序

U_k(n)
为长度第一个向上顺序的序列数
n
。设
U_k(n,f)
是长度的第一个向上顺序
n
和第一个数字
f
的序列数。类似的定义是
duk(n)
duk(n,f)

那么长度
n
(对于
n>1
)的序列数为:

同样的论点给出:

U_k(n, f) = sum D_k(n-1, s) for s = f+1 ... k
          = sum U_k(n-1, s) for s = 1 ... k-f
U_k(1, f) = 1
编辑:

实现稍微简单一些
M(n,k)
返回第n行(从后面),并且
C(n,k)
统计序列数

def M(n, k):
    if n == 1: return [1]*k
    m = M(n-1, k)
    return [sum(m[:i]) for i in xrange(k)][::-1]

def C(n, k):
    if n < 1: return 0
    if n == 1: return k
    return 2*sum(M(n,k))
defm(n,k):
如果n==1:返回[1]*k
m=m(n-1,k)
返回xrange(k)中i的[sum(m[:i])[::-1]
def C(n,k):
如果n<1:返回0
如果n==1:返回k
返回2*和(M(n,k))
可能的重复:
def M(n, k):
    if n == 1: return [1]*k
    m = M(n-1, k)
    return [sum(m[:i]) for i in xrange(k)][::-1]

def C(n, k):
    if n < 1: return 0
    if n == 1: return k
    return 2*sum(M(n,k))