Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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
Algorithm 序列数的计算_Algorithm_Combinatorics - Fatal编程技术网

Algorithm 序列数的计算

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,

我看到了以下我无法解决的问题。什么样的算法可以解决这个问题

我们得到了一个正整数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, 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;
}