Algorithm 使用K个字母查找大小为N的回文的总数
使用K个字母查找长度为N的回文的总数,以便长度为2到N-1的任何前缀都不是回文 已尝试Algorithm 使用K个字母查找大小为N的回文的总数,algorithm,permutation,dynamic-programming,palindrome,discrete-mathematics,Algorithm,Permutation,Dynamic Programming,Palindrome,Discrete Mathematics,使用K个字母查找长度为N的回文的总数,以便长度为2到N-1的任何前缀都不是回文 已尝试K*((K-1)^(Math.ceil((N-2)/2)) 第一个位置可以容纳K个字母。第二个可以是K-1,除了第一个。第三种情况也是如此。 因为我们需要用字母填充的地方有一半,其余的都会用同样的字母来填充。但这不是正确的解决方案。表示M=\ceil{N/2}。该公式基于一个简单的观察结果,即如果长度N的回文具有长度小于N的非平凡(即长度至少2)回文前缀,则其具有长度最多为M的非平凡回文前缀 如果我们用f(n)
K*((K-1)^(Math.ceil((N-2)/2))
第一个位置可以容纳K个字母。第二个可以是K-1,除了第一个。第三种情况也是如此。
因为我们需要用字母填充的地方有一半,其余的都会用同样的字母来填充。但这不是正确的解决方案。表示
M=\ceil{N/2}
。该公式基于一个简单的观察结果,即如果长度N
的回文具有长度小于N
的非平凡(即长度至少2
)回文前缀,则其具有长度最多为M
的非平凡回文前缀
如果我们用f(n)
表示长度n
的好回文数(那些没有长度介于2
和n-1
之间的回文前缀的回文数),我们可以通过从回文总数中减去坏回文数来计算f(n)
。通过以上观察,每个坏回文都有一个最小的非平凡回文前缀,长度L
,介于2
和M
(包括)之间,必须是好回文。每个L
都有f(L)
这样的前缀,它们中的任何一个都可以以K^{M-L}
的方式扩展为长度N
的回文,因此
f(2) = K
f(N) = K^M - \sum_{L=2}^{M} K^{M - L}f(L)
我编写了一个Python脚本来检查
N
和K
的小值
游乐场:
导入工具
进口itertools
导入字符串
@functools.lru_cache()
def f(N,K):
如果N==2:
返回K
M=(N+1)//2
返回K**M-和(范围(2,M+1)内的L的K**(M-L)*f(L,K)
def是回文:
返回s[:(len(s)+1)//2]==s[len(s)//2:[::-1]
定义f(N,K):
字母表=字符串。ascii_小写[:K]
ret=0
对于itertools.product中的t(字母表,重复=N):
s=”“.加入(t)
如果是回文,而不是任何(范围(2,N)内的i是回文(s[:i]):
ret+=1
回程网
打印(全部)(
f(N,K)=f(N,K)
适用于范围(12)内的N
对于范围(4)中的K
))
$K$字母必须是不同的吗?您如何知道您的解决方案不正确?有什么不正确的地方吗?您标记了动态编程,但您的解决方案不涉及DP——您有理由认为它应该吗?是的,K字母是不同的,但您可以在同一字符串中多次使用它们。可能需要DP来解决此问题,但不确定。此解决方案不包含所有可能的回文字符串。