假设我们有一个长度为X的布尔数组。唯一的规则是,TRUE不得在相邻位置出现两次。特别是只允许使用假值的数组。例如。禁止这样做:[1,1,0,0,0]并且允许这些:[1,0,0,0,0],[0,0,0,0,0],[1,0,1 ,0,1]等。如何使用动态编程来确定有多少个不同的有效长度为X的有效数组?
答案 0 :(得分:3)
让 T i 为满足您条件的长度为 i 并以{结尾的数组的数量{1}},令 F i 为满足条件的长度为 i 的数组的数量, 不以1
结尾。
然后:
1
结尾的长度 i +1的数组都由一个满足您的条件并且符合的长度 i 的数组组成不是以1
结尾,并在末尾加上一个额外的1
。)1
的情况下,长度为 i 符合您的条件,最后加上一个额外的1
。因此,您只需编写一个循环即可计算 F i 和 T 从0到 X 的每个 i 的i ,然后返回 F X < / em> + T X 。
(本质上,这甚至不是动态编程,因为您不需要存储部分值; F i +1 和 T i +1 仅取决于 F i < / sub>和 T i 。所以这是 O ( X )时间和 O (1)空格。)
答案 1 :(得分:0)
我认为您无需使用DP即可计算数量。由于您知道长度为N的数组总数,因此为'2 ^ N'。
现在,您需要扣除那些bad
相邻的1
不合格的数组。对于长度为N的数组,有以下几种情况
1. the array has no 1's, only one case, and it is a valid array
2. the array has one 1's, all cases are valid
3. the array has two 1's, there are N - 1 cases which are not valid
4. the array has three 1's, there are (N-1) * (N-2) / 2 cases which are not valid
...
答案 2 :(得分:0)
dp解决方案将具有两个状态参数。一个是数组的位置,另一个是前一个位置的值。如果前一个位置的值为1,那么您只能选择0。如果前一个位置的值为0,那么您可以选择1或0。希望这对您有所帮助。
答案 3 :(得分:0)
您实际上并不需要动态编程。 对于数组长度X,有效数组的数目为Fib(X + 1),其中Fib是斐波纳契数的数组。
X = 1:有效数组:2
X = 2:有效数组:3
X = 3:有效数组:5
X = 4:有效数组:8
以此类推...
演示:
让我们假设我们正在寻找X的数组,并且知道X-1的有效数组的数量。我们可以在每个X-1长度数组的末尾随意添加零,所以到目前为止是F(X-1)。我们还可以在每个以0结尾的X-1数组的末尾添加一个“ 1”。但是这些数组中有多少个呢?好吧,它正是F(X-2),因为我们可以完全相同的方式生成零结尾的X-1长度数组:通过在每个X-2长度数组的末尾添加零。所以F(X)= F(X-1)+ F(X-2) 这就是斐波那契数组的定义。
我们要做的就是手动计算前两个元素以确定是菲波纳奇数组还是已移位。
您甚至可以找到一个公式来计算斐波那契数组的第N个元素,因此可以在O(1)中求解。