Algorithm 序列数的计算
我看到了以下我无法解决的问题。什么样的算法可以解决这个问题 我们得到了一个正整数n。设A是长度为n的所有可能字符串的集合,其中字符来自集合{1,2,3,4,5,6},即掷n次骰子的结果。A的多少个元素至少包含以下一个字符串作为子字符串:Algorithm 序列数的计算,algorithm,combinatorics,Algorithm,Combinatorics,我看到了以下我无法解决的问题。什么样的算法可以解决这个问题 我们得到了一个正整数n。设A是长度为n的所有可能字符串的集合,其中字符来自集合{1,2,3,4,5,6},即掷n次骰子的结果。A的多少个元素至少包含以下一个字符串作为子字符串: 1, 2, 3, 4, 5, 6 1, 1, 2, 2, 3, 3 4, 4, 5, 5, 6, 6 1, 1, 1, 2, 2, 2 3, 3, 3, 4, 4, 4 5, 5, 5, 6, 6, 6 1, 1, 1, 1, 1, 1 2, 2, 2, 2,
1, 2, 3, 4, 5, 6
1, 1, 2, 2, 3, 3
4, 4, 5, 5, 6, 6
1, 1, 1, 2, 2, 2
3, 3, 3, 4, 4, 4
5, 5, 5, 6, 6, 6
1, 1, 1, 1, 1, 1
2, 2, 2, 2, 2, 2
3, 3, 3, 3, 3, 3
4, 4, 4, 4, 4, 4
5, 5, 5, 5, 5, 5
6, 6, 6, 6, 6, 6
我想知道某种递归方法,但当我试图解决这个问题时,我弄得一团糟。你的递归方法有什么问题,你能详细说明一下吗,无论如何,这可以用O(6^n)中的递归方法解决,但可以用dp优化,只需要跟踪最后6个元素,所以它可以在O(6*2^6*n)和dp中完成
rec(字符串cur,int-step){
如果(步骤==n)返回0;
int ans=0;
for(字符c在{'1','2','3','4','5','6'}中){
如果(电流长度<6)电流+=c
否则{
shift(cur,1)//将字符串向左移动1步
cur[5]=c//将新元素添加到字符串的末尾
}
if(cur in list)ans+=1+rec(cur,step+1)//问题中描述的列表
else ans+=rec(当前,步骤+1)
}
返回ans;
}
我建议阅读。这将基于一组字符串构造一个有限状态机。(如果您的字符串列表是固定的,您甚至可以手动执行此操作。)
一旦有了一个有限状态机(大约有70个状态),就应该添加一个额外的吸收状态来标记何时检测到任何字符串
现在,您的问题归结为查找6**n字符串中有多少字符串在通过状态机后最终处于吸收状态
可以通过将状态机表示为矩阵来实现这一点。当添加一个字母时,条目M[i,j]表示从状态j到达状态i的方法的数量
最后,计算出一个矩阵,该矩阵的幂n应用于一个输入向量,除了初始状态对应位置的1之外,该输入向量都是零。吸收状态位置的数字将告诉你字符串的总数
(您可以使用标准在O(logn)时间内生成此答案。)我在想,我有6^5=7776个案例,最后五次抛出可能会导致递归处理所有案例可能会很困难。我真的不理解你的评论,6^5个案例你是说6^n吗?递归处理所有案例的方式可能会很困难?我觉得很简单,代码在上面解释。我的意思是6^5。要找出答案长度为n的字符串中有多少个包含合适的字符串我必须找出长度为n-1的字符串的数量不包含这12个字符串中的一个,而是在末尾有正确的五位数字,以便将最后一个字符连接到末尾,得到一个末尾有合适子字符串的字符串。我假设
n>=6
,因为您所需的子字符串的长度为6。如果nCan子字符串被重复,您可以假设或者不太难放入?我的意思是,1、2、3、4、5、6、1、2、3、4、5、6
,当与1、2、3、4、5、1、2、3、5
进行比较时,是否应将1、2、3、4、5、5
计算为单独的有效字符串?编辑:结果表明s对解决方案不重要。它们可以重复。由于这两个示例不同,但都包含子字符串1、2、3、4、5、6
,因此这两个字符串是两个不同的有效字符串。
rec (String cur, int step) {
if(step == n) return 0;
int ans = 0;
for(char c in { '1', '2', '3', '4', '5', '6' } {
if(cur.length < 6) cur += c
else {
shift(cur,1) // shift the string to the left by 1 step
cur[5] = c // add the new element to the end of the string
}
if(cur in list) ans += 1 + rec(cur, step+1) // list described in the question
else ans += rec(cur, step+1)
}
return ans;
}