关注公众号【算法码上来】,每日算法干货马上就来!

题目链接:EOJ2854
题意
在0和1组成的长度为$n(1 \le n \le 31)$的字符串中,统计包含$m(1 \le m \le n)$个连续1子串的字符串的个数。
题解
这题要用到的算法思想是动态规划。
首先令$f(n, m)$表示长度为$n(1 \le n \le 31)$的字符串中,包含$m(1 \le m \le n)$个连续1子串的字符串的个数。考虑最后一位,也就是第$n$位的取值,可以分为两种情况:
- 如果第$n$位为0,那么只能在前面的$n-1$位里取长度为$m$的连续1子串,那么答案就是
\[f(n-1,m)\] - 如果第$n$位为1,那么考虑两种情况。
一种是最后$m$位全为1,那么前面$n-m$位就可以任意取值,答案为
\[2^{n-m}\]
另一种情况是最后$m$位不全为1,也就是存在某一位为0,枚举最后一位0出现的位置,可能出现在第$n-1$位、第$n-2$位,一直到第$n-m+1$位,不管最后一个0出现在哪里,都要在之前的字符串中重新出现长度为$m$的连续1子串,所以答案是
\[\sum\limits_{n - m \le i \le n - 2} {f(i,m)} \]
所以最终的答案就是
\[f(n,m) = {2^{n - m}} + \sum\limits_{n - m \le i \le n - 1} {f(i,m)} \]
进一步化简这个式子,用$n-1$替换$n$可以得到
\[f(n - 1,m) = {2^{n - m - 1}} + \sum\limits_{n - m - 1 \le i \le n - 2} {f(i,m)} \]
两式相减可以得到
\[f(n,m) = {2^{n - m - 1}} + 2f(n - 1,m) - f(n - m - 1,m)\]
边界条件为:
- 当$n < m$时,$f(n,m)=0$。
- 当$n = m$时,$f(n,m)=1$。
代码
|