简体   繁体   English

计算我可以在数组中拥有唯一数字的方法数

[英]Counting number of ways I can have unique numbers in array

I am trying to find the number of ways to construct an array such that consecutive positions contain different values.我试图找到构造数组以使连续位置包含不同值的方法的数量。

Specifically, I need to construct an array with elements such that each element 1 between and k, all inclusive.具体来说,我需要构造一个包含元素的数组,使得每个元素介于 1 和 k 之间,包括所有元素。 I also want the first and last elements of the array to be 1 and x.我还希望数组的第一个和最后一个元素是 1 和 x。

Complete problem statement:完整的问题陈述:

在此处输入图像描述

Here is what I tried:这是我尝试过的:

 def countArray(n, k, x):
    # Return the number of ways to fill in the array.
    if x > k:
        return 0
    if x == 1:
        return 0
    
    def fact(n):
        if n == 0:
            return 1
        fact_range = n+1
        T = [1 for i in range(fact_range)]
        for i in range(1,fact_range):
            T[i] = i * T[i-1]
        return T[fact_range-1]
    
    ways = fact(k) / (fact(n-2)*fact(k-(n-2)))
    return int(ways)

In short, I did K(C)N-2 to find the ways.简而言之,我做了K(C)N-2来寻找方法。 How could I solve this?我怎么能解决这个问题?

It passes one of the base case with inputs as countArray(4,3,2) but fails for 16 other cases.它通过输入为countArray(4,3,2)的基本案例之一,但在其他 16 个案例中失败。

Let X(n) be the number of ways of constructing an array of length n, starting with 1 and ending in x (and not repeating any numbers).X(n)为构造长度为 n 的数组的方法数,从 1 开始到 x 结束(并且不重复任何数字)。 Let Y(n) be the number of ways of constructing an array of length n, starting with 1 and NOT ending in x (and not repeating any numbers).Y(n)为构造长度为 n 的数组的方法数,从 1 开始,不以 x 结尾(并且不重复任何数字)。

Then there's these recurrence relations (for n>1)然后是这些递归关系(对于 n>1)

X(n+1) = Y(n)
Y(n+1) = X(n)*(k-1) + Y(n)*(k-2)

In words: If you want an array of length n+1 ending in x, then you need an array of length n not ending in x.换句话说:如果你想要一个长度为 n+1 的数组以 x 结尾,那么你需要一个长度为 n 且不以 x 结尾的数组。 And if you want an array of length n+1 not ending in x, then you can either add any of the k-1 symbols to an array of length n ending in x, or you can take an array of length n not ending in x, and add any of the k-2 symbols that aren't x and don't repeat the last value.如果您想要一个长度为 n+1 且不以 x 结尾的数组,那么您可以将任何 k-1 个符号添加到以 x 结尾的长度为 n 的数组中,或者您可以获取一个长度为 n 且不以 x 结尾的数组x,并添加任何不是 x 且不重复最后一个值的 k-2 个符号。

For the base case, n=1 , if x is 1 then X(1)=1 , Y(1)=0 otherwise, X(1)=0 , Y(1)=1对于基本情况, n=1 ,如果x1X(1)=1Y(1)=0否则, X(1)=0Y(1)=1

This gives you an O(n)-time method of computing the result.这为您提供了计算结果的 O(n) 时间方法。

def ways(n, k, x):
    M = 10**9 + 7
    wx = (x == 1)
    wnx = (x != 1)
    for _ in range(n-1):
        wx, wnx = wnx, wx * (k-1) + wnx*(k-2)
        wnx = wnx % M
    return wx

print(ways(100, 5, 2))

In principle you can reduce this to O(log n) by expressing the recurrence relations as a matrix and computing the matrix power (mod M), but it's probably not necessary for the question.原则上,您可以通过将递归关系表示为矩阵并计算矩阵幂 (mod M) 将其减少到 O(log n),但这可能不是问题所必需的。

[Additional working] [附加工作]

We have the recurrence relations:我们有递归关系:

X(n+1) = Y(n)
Y(n+1) = X(n)*(k-1) + Y(n)*(k-2)

Using the first, we can replace the Y(_) in the second with X(_+1) to reduce it down to a single variable.使用第一个,我们可以将第二个中的Y(_)替换为X(_+1)以将其缩减为单个变量。 Then:然后:

X(n+2) = X(n)*(k-1) + X(n+1)*(k-2)

Using standard techniques, we can solve this linear recurrence relation exactly.使用标准技术,我们可以准确地解决这种线性递归关系。

In the case x,=1: we have:在 x,=1 的情况下:我们有:

X(n) = ((k-1)^(n-1) - (-1)^n) / k

And in the case x=1, we have:在 x=1 的情况下,我们有:

X(n) = ((k-1)^(n-1) - (1-k)(-1)^n)/k

We can compute these mod M using Fermat's little theorem because M is prime.我们可以使用费马小定理计算这些 mod M,因为 M 是素数。 So 1/k = k^(M-2) mod M.所以 1/k = k^(M-2) mod M。

Thus we have (with a little bit of optimization) this short program that solves the problem and runs in O(log n) time:因此,我们有(经过一点优化)这个解决问题并在 O(log n) 时间内运行的短程序:

def ways2(n, k, x):
    S = -1 if n%2 else 1
    return ((pow(k-1, n-1, M) + S) * pow(k, M-2, M) - S*(x==1)) % M

could you try this DP version: (it's passed all tests) (it's inspired by @PaulHankin and take DP approach - will run performance later to see what's diff for big matrix)你能试试这个DP版本吗:(它已通过所有测试)(它的灵感来自@PaulHankin 并采用 DP 方法 - 稍后将运行性能以查看大矩阵的差异)

def countArray(n, k, x):
    # Return the number of ways to fill in the array.
    big_mod = 10 ** 9 + 7
    dp = [[1], [1]]
    if x == 1: 
        dp = [[1], [0]]
    else:
        dp = [[1], [1]]
    
    for _ in range(n-2):
        dp[0].append(dp[0][-1] * (k - 1) % big_mod)
        dp[1].append((dp[0][-1] - dp[1][-1]) % big_mod)
    return dp[1][-1]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 计算从列表中选择唯一元素的方法的数量 - Counting number of ways to select unique elements from list of lists 查找与Python中的数字相加的唯一数字的方法数量 - The number of ways to find unique numbers that sum to a number in Python 计算已排序数组子集中唯一值的数量 - Counting number of unique values in subset of sorted array 我有一个数字列表和一定的和,并且我需要计算产生该和的可能方法 - i have a list of numbers and a certain sum, and i need to calculate the possible number of ways to generate that sum 关于计数多维数组唯一数的输出 - regarding the output of counting the unique numbers of multi-dimension array 如何在python中生成8个唯一数字的数组? - How can I generate an array of 8 unique numbers in python? 如何计算给定字符串可以拆分为素数的方式数? - How to count the number of ways a given string can be split into prime numbers? 计算python中numpy数组列中特定数字的数量 - Counting number of specific numbers in the column of a numpy array in python Output 应该是数组中数字的总和,但不包括 13 和后面的数字 - Output should be Sum of numbers in array but not counting 13 and number following it 数组中数字的总和,不包括 13 和紧随其后的数字(CodingBat 谜题) - Sum of numbers in array, not counting 13 and number directly after it (CodingBat puzzle)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM