题目链接
Leetcode2466. 统计构造好字符串的方案数
rating : 1694
题目描述
给你整数 zero
,one
,low
和 high
,我们从空字符串开始构造一个字符串,每一步执行下面操作中的一种:
- 将
'0'
在字符串末尾添加zero
次。 - 将
'1'
在字符串末尾添加one
次。 - 以上操作可以执行任意次。
如果通过以上过程得到一个 长度 在 low
和 high
之间(包含上下边界)的字符串,那么这个字符串我们称为 好 字符串。
请你返回满足以上要求的 不同 好字符串数目。由于答案可能很大,请将结果对 1 0 9 + 7 10^9 + 7 109+7 取余 后返回。
示例1
输入:low = 3, high = 3, zero = 1, one = 1
输出:8
解释:
一个可能的好字符串是 “011” 。
可以这样构造得到:“” -> “0” -> “01” -> “011” 。
从 “000” 到 “111” 之间所有的二进制字符串都是好字符串。
示例2
输入:low = 2, high = 3, zero = 1, one = 2
输出:5
解释:好字符串为 “00” ,“11” ,“000” ,“110” 和 “011” 。
提示
- 1 ≤ l o w ≤ h i g h ≤ 105 1 \leq low \leq high \leq 105 1≤low≤high≤105
- 1 ≤ z e r o , o n e ≤ l o w 1 \leq zero, one \leq low 1≤zero,one≤low
解法:dp(爬楼梯)
我们定义 f ( i ) f(i) f(i) 是长度为 i i i 的好字符串的数量。按照定义,我们最终返回的就是 ∑ i = l o w h i g h f [ i ] \sum_{i = low}^{high}f[i] i=low∑highf[i]
对于当前枚举的长度 i i i :
- i ≥ o n e i \geq one i≥one, f [ i ] = f [ i ] + f [ i − o n e ] f[i] = f[i] + f[i - one] f[i]=f[i]+f[i−one];
- i ≥ z e r o i \geq zero i≥zero, f [ i ] = f [ i ] + f [ i − z e r o ] f[i] = f[i] + f[i - zero] f[i]=f[i]+f[i−zero];
初始 f [ 0 ] = 1 f[0] = 1 f[0]=1,表示空串也是一种方案。注意在计算的过程中取模!
时间复杂度: O ( h i g h ) O(high) O(high)
C++代码:
using LL = long long;
const int MOD = 1e9 + 7;
class Solution {
public:
int countGoodStrings(int low, int high, int zero, int one) {
vector<LL> f(high + 5);
f[0] = 1;
LL ans = 0;
for(int i = 1;i <= high;i++)
{
if(i >= one) f[i] = (f[i] + f[i - one]) % MOD;
if(i >= zero) f[i] = (f[i] + f[i - zero]) % MOD;
if(i >= low) ans = (ans + f[i]) % MOD;
}
return ans;
}
};