uacs2024

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

leetcode 2466. 统计构造好字符串的方案数

2466. 统计构造好字符串的方案数

没写出来🤡

题解

法一:记忆化搜索

复制代码
class Solution {
public:
    // 计算在[low, high]范围内,满足'0'的数量不超过zero,'1'的数量不超过one的字符串数量
    int countGoodStrings(int low, int high, int zero, int one) {
        // MOD用于结果取模,防止整数溢出,这里取的是10^9 + 7
        const int MOD = 1'000'000'007;
        
        // 使用一个记忆化数组memo来存储已经计算过的结果,初始化为-1表示未计算
        vector<int> memo(high+1,-1); // 数组大小为high+1,因为i的范围是从0到high

        // 定义一个dfs函数(递归函数),用于计算满足条件的字符串数量
        // 使用lambda表达式和递归函数自身引用(&&dfs)实现递归记忆化搜索
        auto dfs = [&](auto &&dfs,int i) -> int{
            // 如果i小于0,说明当前字符串不满足条件(长度小于0),返回0
            if(i < 0)  return 0;
            // 如果i等于0,说明当前字符串为空字符串,满足条件,返回1
            if(i == 0)  return 1;
            // 尝试从memo中获取已经计算过的结果
            int &res = memo[i];
            // 如果res不等于-1,说明已经计算过,直接返回结果
            if(res != -1)  return res;
            // 递归计算以'0'结尾的字符串数量(减去zero)和以'1'结尾的字符串数量(减去one)
            // 并取模防止溢出,将结果存入memo并返回
            return res = (dfs(dfs,i - zero) + dfs(dfs,i - one)) % MOD;
        };

        // 初始化结果变量
        int res = 0;
        // 遍历low到high之间的每个数字,计算每个数字对应的满足条件的字符串数量并累加
        for(int i = low;i <= high;++i){
            res = (res + dfs(dfs,i)) % MOD;
        }
        // 返回最终结果
        return res;
    }
};
复制代码

法二:递推

复制代码
class Solution {
public:
    int countGoodStrings(int low, int high, int zero, int one) {
        const int MOD = 1'000'000'007;
        int res = 0;
        vector<int> dp(high+1);//dp[i] 表示构造长为 i 的字符串的方案数
        dp[0] = 1;
        for(int i = 1;i <= high;++i){
            if(i >= zero)  dp[i] = dp[i-zero];
            if(i >= one)  dp[i] = (dp[i] + dp[i-one]) % MOD;
            if(i >= low)  res = (res + dp[i]) % MOD;
        }
        return res;
    }
};
复制代码

法三:递推优化

复制代码
class Solution {
public:
    int countGoodStrings(int low, int high, int zero, int one) {
        int g = gcd(zero, one);
        low = (low - 1) / g + 1;
        high /= g;
        zero /= g;
        one /= g;

        const int MOD = 1'000'000'007;
        int res = 0;
        vector<int> dp(high+1);//dp[i] 表示构造长为 i 的字符串的方案数
        dp[0] = 1;
        for(int i = 1;i <= high;++i){
            if(i >= zero)  dp[i] = dp[i-zero];
            if(i >= one)  dp[i] = (dp[i] + dp[i-one]) % MOD;
            if(i >= low)  res = (res + dp[i]) % MOD;
        }
        return res;
    }
};
复制代码

 

posted on   ᶜʸᵃⁿ  阅读(29)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示