数位DP LeetCode 600 不含连续1的非负整数
2023-12-31 10:52:59
一、题目
1、题目描述
给定一个正整数?
n
?,请你统计在?[0, n]
?范围的非负整数中,有多少个整数的二进制表示中不存在?连续的 1?。示例 1:
输入: n = 5 输出: 5 解释: 下面列出范围在 [0, 5] 的非负整数与其对应的二进制表示: 0 : 0 1 : 1 2 : 10 3 : 11 4 : 100 5 : 101 其中,只有整数 3 违反规则(有两个连续的 1 ),其他 5 个满足规则。
2、接口描述
?
class Solution {
public:
int findIntegers(int n) {
}
};
3、原题链接
二、解题报告
1、思路分析
本题是数位DP的模板题,关于数位DP笔者将于明日发布详细讲解,这里仅给出本题解法
我们设计状态f[i][j]为剩余i位未处理,上一位为j情况下目标数字的数目,这也是数位dp问题通用状态设计
那么我们只需要枚举下一位即可,如果前面的位严格小于给定数字的对应位,那么可以从0枚举到9,否则只能枚举到给定数字对应位
对于连续1的情况不进行枚举即可
2、复杂度
时间复杂度: O(log n)?空间复杂度:O(log n)
3、代码详解
?
int f[32][32] , d[32] , cnt = 0;
class Solution {
public:
Solution()
{memset(f , -1 , sizeof(f));}
int dfs(int n , int pre , bool lim)
{
if(!n) return 1;
if(lim && ~f[n][pre]) return f[n][pre];
int ceil = lim ? 1 : d[n];
int res = 0;
for(int i = 0 ; i <= ceil ; i++)
if(pre == 1 && i == 1) continue;
else res += dfs(n - 1 , i , lim || i < ceil);
if(lim)
f[n][pre] = res;
return res;
}
int getnum(int x)
{
cnt = 0;
while(x) d[++cnt] = x % 2 , x /= 2;
return dfs(cnt , 0 , false);
}
int findIntegers(int n) {
return getnum(n);
}
};
文章来源:https://blog.csdn.net/EQUINOX1/article/details/135313324
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!