【数位dp】【C++算法】600. 不含连续1的非负整数

news2024/9/24 9:17:06

作者推荐

【矩阵快速幂】封装类及测试用例及样例

涉及知识点

数位dp

LeetCode600. 不含连续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:
输入: n = 1
输出: 2
示例 3:
输入: n = 2
输出: 3
提示:
1 <= n <= 109

数位dp

直接使用封装好的类。
结果:int 最小值:‘0’ 最大值:‘1’
当前值为’1’时,前值必须为‘0’。
当前值为’0’时,前值‘0’ ‘1’ 皆可。

代码

封装类

template<class ELE, class ResultType, ELE minEle, ELE maxEle>
class CLowUperr
{
public:
	CLowUperr(int iResutlCount):m_iResutlCount(iResutlCount)
	{
	}
	void Init(const ELE* pLower, const ELE* pHigh, int iNum)
	{
		m_vPre.assign(4, vector<ResultType>(m_iResutlCount));
		if (iNum <= 0)
		{
			return;
		}
		InitPre(pLower, pHigh);
		iNum--;
		while (iNum--)
		{
			pLower++;
			pHigh++;
			vector<vector<ResultType>> dp(4, vector<ResultType>(m_iResutlCount));
			OnInitDP(dp);
			//处理非边界
			for (auto tmp = minEle; tmp <= maxEle; tmp++)
			{
				OnEnumOtherBit(dp[0], m_vPre[0], tmp);
			}
			//处理下边界
			OnEnumOtherBit(dp[1], m_vPre[1], *pLower);
			for (auto tmp = *pLower + 1; tmp <= maxEle; tmp++)
			{
				OnEnumOtherBit(dp[0], m_vPre[1], tmp );
			}
			//处理上边界
			OnEnumOtherBit(dp[2], m_vPre[2], *pHigh );
			for (auto tmp = minEle; tmp < *pHigh; tmp++)
			{
				OnEnumOtherBit(dp[0], m_vPre[2], tmp );
			}
			//处理上下边界
			if (*pLower == *pHigh)
			{
				OnEnumOtherBit(dp[3], m_vPre[3], *pLower);
			}
			else
			{
				OnEnumOtherBit(dp[1], m_vPre[3], *pLower );
				for (auto tmp = *pLower + 1; tmp < *pHigh; tmp++)
				{
					OnEnumOtherBit(dp[0], m_vPre[3], tmp );
				}
				OnEnumOtherBit(dp[2], m_vPre[3], *pHigh );
			}
			m_vPre.swap(dp);
		}
	}
	/*ResultType Total(int iMinIndex, int iMaxIndex)
	{
		ResultType ret;
		for (int status = 0; status < 4; status++)
		{
			for (int index = iMinIndex; index <= iMaxIndex; index++)
			{
				ret += m_vPre[status][index];
			}
		}
		return ret;
	}*/
protected:
	const int m_iResutlCount;
	void InitPre(const ELE* const pLower, const ELE* const pHigh)
	{
		for (ELE cur = *pLower; cur <= *pHigh; cur++)
		{
			int iStatus = 0;
			if (*pLower == cur)
			{
				iStatus = *pLower == *pHigh ? 3 : 1;
			}
			else if (*pHigh == cur)
			{
				iStatus = 2;
			}
			OnEnumFirstBit(m_vPre[iStatus], cur);
		}
	}

	virtual void OnEnumOtherBit(vector<ResultType>& dp, const vector<ResultType>& vPre, ELE curValue) = 0;

	virtual void OnEnumFirstBit(vector<ResultType>& vPre, const ELE curValue) = 0;
	virtual void OnInitDP(vector<vector<ResultType>>& dp)
	{

	}
	vector<vector<ResultType>> m_vPre;
};

核心代码

class CCharLowerUper : public CLowUperr<char, int, '0', '1'>
{
public:
	using CLowUperr<char, int, '0', '1'>::CLowUperr;
	int Total(int iMinIndex, int iMaxIndex)
	{
		int ret = 0;
		for (int index = iMinIndex; index <= iMaxIndex; index++)
		{
			int cur = 0;
			for (int status = 0; status < 4; status++)
			{
				cur += m_vPre[status][index];
			}
			ret += cur;
		}
		return ret;
	}
protected:

	virtual void OnEnumFirstBit(vector<int>& vPre, const char curValue)
	{
		const int index = curValue - '0';
		vPre[index]++;
	}
	virtual void OnEnumOtherBit(vector<int>& dp, const vector<int>& vPre, char curValue)
	{
		const int index = curValue - '0';
		if (1 == index)
		{
			dp[index] += vPre[0];
		}
		else
		{
			dp[index] += vPre[0] + vPre[1];
		}		
	}

};

class Solution {
public:
	int findIntegers(int n) {
		 string strN ;
		 while (n > 0)
		 {
			 strN += ((n & 1) ? "1" : "0");
			 n /= 2;
		 }
		 std::reverse(strN.begin(), strN.end());
		const int len = strN.length();
		int iRet = 0;
		for (int i = 1; i < len; i++)
		{
			CCharLowerUper lu(2);
			lu.Init(("1" + string(i - 1, '0')).c_str(), string(i, '1').c_str(), i);
			iRet += lu.Total(0, 1);
		}

		CCharLowerUper lu(2);
		lu.Init(("1" + string(len - 1, '0')).c_str(), strN.c_str(), len);
		iRet += lu.Total(0, 1);
		return 1 + iRet;
	}	
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}
}


int main()
{
	int n;
	{
		Solution sln;
		n = 5;
		auto res = sln.findIntegers(n);
		Assert(5, res);
	}
	{
		Solution sln;
		n = 1;
		auto res = sln.findIntegers(n);
		Assert(2, res);
	}
	{
		Solution sln;
		n = 2;
		auto res = sln.findIntegers(n);
		Assert(3, res);
	}
	{
		Solution sln;
		n = 10;
		auto res = sln.findIntegers(n);
		Assert(8, res);
	}
	{
		Solution sln;
		n = 100;
		auto res = sln.findIntegers(n);
		Assert(34, res);
	}
}

2013年1月版

class Solution {
public:
int findIntegers(int n) {
if (1 == n)
{
return 2;
}
std::vector bits;
int tmp = n;
while (tmp > 0)
{
bits.insert(bits.begin(), tmp % 2);
tmp >>= 1;
}
const int iBitNum = bits.size();
//dp[i][0]表示i位 0结尾的可能数
vector<vector> dp(iBitNum, vector(2));//
dp[1][0] = 1;
dp[1][1] = 1;
for (int i = 2; i < dp.size(); i++)
{
dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
dp[i][1] = dp[i - 1][0];
}
int iNum = 0;// dp[iBitNum - 1][0] + dp[iBitNum - 1][1];
int iPreBit = 0;
for (int i = 0; i < iBitNum; i++)
{
const int iCurBit = bits[i];
if (i + 1 == iBitNum)
{
iNum += iCurBit ;
}
else
{
if (1 == iCurBit)
{
iNum += dp[iBitNum - i - 1][0] + dp[iBitNum - i - 1][1];
}
}
if (iCurBit & iPreBit)
{
break;
}
if (i + 1 == iBitNum)
{
iNum++;
}
iPreBit = iCurBit;
}
return iNum;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 **C+

+17**
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1388081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浏览器打印无法显示单选框选中效果

上面是原代码&#xff0c;我点击打印&#xff0c;出现打印页面&#xff0c;但单选框并未勾选中&#xff0c;我在外部放了一模一样的代码是能勾选上的&#xff0c;于是我对打印页的input单选框进行分析&#xff0c;发现他丢失了checked属性。然后通过gpt分析原因。得知了default…

RK3399平台入门到精通系列讲解(外设篇)热成像传感器MLX90640 JNI控制程序

文章目录 JNI回调函数回调函数的实现驱动可以详看:链接 JNI 文件:native-lib.cpp

领域特定语言(Domain-Specific Language, DSL)在 Visual Studio 2022中的实验——建立领域模型

一、环境 dotnet --version 8.0.101 Microsoft Visual Studio Enterprise 2022 (64 位) - Current 版本 17.8.4 已安装组件 ComponentLinkVisual Studiohttp://go.microsoft.com/fwlink/?LinkId185579Visual Studio SDKhttps://go.microsoft.com/fwlink/?li…

RabbitMQ的安装使用

RabbitMQ是什么&#xff1f; MQ全称为Message Queue&#xff0c;消息队列&#xff0c;在程序之间发送消息来通信&#xff0c;而不是通过彼此调用通信。 RabbitMQ 主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时&#xff0c;消费者无法快速消费&#xff0c;…

图解结算平台:准确高效给商户结款

这是《百图解码支付系统设计与实现》专栏系列文章中的第&#xff08;4&#xff09;篇。 本章主要讲清楚支付系统中商户结算涉及的基本概念&#xff0c;产品架构、系统架构&#xff0c;以及一些核心的流程和相关领域模型、状态机设计等。 1. 前言 收单结算是支付系统最重要的子…

曲面上偏移命令的查找

今天学习老王的SW绘图时&#xff0c;遇到一个命令找不到&#xff0c;查询了一会终于找到了这个命令&#xff0c;防止自己忘记&#xff0c;特此记录一下&#xff0c;这个命令就是“曲面上偏移”&#xff0c;网上好多的教程都是错误的&#xff0c;实际上这个命令没有在曲面里面&a…

蓝桥杯备赛 | 洛谷做题打卡day3

蓝桥杯备赛 | 洛谷做题打卡day3 sort函数真的很厉害&#xff01; 文章目录 蓝桥杯备赛 | 洛谷做题打卡day3sort函数真的很厉害&#xff01;【深基9.例1】选举学生会题目描述输入格式输出格式样例 #1样例输入 #1 样例输出 #1 我的一些话 【深基9.例1】选举学生会 题目描述 学校…

封装日期时间组件

概述 该组件包含日期选择&#xff0c;任意时间选择、固定时间点选择。 子组件代码(date-picker.vue) <template><div id"date_picker"><el-popover placement"top" width"322" trigger"click" ref"popover&quo…

【学习心得】图解Git命令

图解Git命令的图片是在Windows操作系统中的Git Bash里操作截图。关于Git的下载安装和理论学习大家可以先看看我写的另两篇文章。链接我放在下面啦&#xff1a; 【学习心得】Git快速上手_git学习心得-CSDN博客 【学习心得】Git深入学习-CSDN博客 一、初始化仓库 命令&#xff…

Go后端开发 -- 数组 slice map range

Go后端开发 – 数组 && slice && map && range 文章目录 Go后端开发 -- 数组 && slice && map && range一、数组1.数组的声明和初始化2.数组的传参 二、slice切片1.slice的定义和初始化2.len()和cap()函数3.空切片4.切片截取5…

基于深度学习的实例分割的Web应用

基于深度学习的实例分割的Web应用 1. 项目简介1.1 模型部署1.2 Web应用 2. Web前端开发3. Web后端开发4. 总结 1. 项目简介 这是一个基于深度学习的实例分割Web应用的项目介绍。该项目使用PaddlePaddle框架&#xff0c;并以PaddleSeg训练的图像分割模型为例。 1.1 模型部署 …

智能反射面—流形优化

使用Manopt工具箱适合优化最小化问题&#xff0c;如果你的优化问题是最大化问题&#xff0c;那么需要将其转换为最小化问题然后使用Manopt工具箱求解。 具体安装过程 Matlab添加Manopt - 知乎 (zhihu.com) 优化问题 clc,clear; close all; srng(1);%rand seed N10; GR_num1e3…

MathType中文网站2024最新版本下载及嵌入word教程

MathType是一款专业的数学公式编辑器,兼容Office word,excel等700多种程序,用于编辑数学试卷、书籍、报刊、论文、幻灯演示等文档轻松输入各种复杂的数学公式和符号。 MathType是一款功能强大的数学公式编辑器&#xff0c;广泛用于编写和编辑数学公式。Word是微软公司推出的文…

C语言练习day6

关于牛客网运行超时的问题 [NOIP2008]ISBN号码_牛客题霸_牛客网 题目 思路&#xff1a;这个题目重点在怎么去把这个ISBN号码正确输入&#xff0c;其实这个题目已经提示了我们一点信息&#xff1a;输入描述里说&#xff0c;是一个字符序列&#xff0c;其实我们就可以把这个IS…

中国社科院与新加坡社科大联合培养博士——单证还是双证?

有关博士学位&#xff0c;我想不用多说相信很多人都清楚&#xff0c;博士是我国学位等级中目前为止的最高学位&#xff0c;拥有了博士学位就相当于拥有了最高荣誉&#xff0c;但是&#xff0c;我国教育形式另开设了学历教育&#xff0c;对于学历教育的形式&#xff0c;在职博士…

MIT 6s081 lab1:Xv6 and Unix utilities

Lab1: Xv6 and Unix utilities 作业网址&#xff1a;https://pdos.csail.mit.edu/6.828/2020/labs/util.html Boot xv6(easy) 下载&#xff0c;启动xv6系统 $ git clone git://g.csail.mit.edu/xv6-labs-2020 Cloning into xv6-labs-2020... ... $ cd xv6-labs-2020 $ git …

Maxwell数据同步(增量)

1. Maxwell简介 1.1 Maxwell概述 Maxwell 是由美国Zendesk公司开源&#xff0c;用Java编写的MySQL变更数据抓取软件。它会实时监控Mysql数据库的数据变更操作&#xff08;包括insert、update、delete&#xff09;&#xff0c;并将变更数据以 JSON 格式发送给 Kafka、Kinesi等流…

浅谈智慧路灯安全智能供电方案设计

摘要: 智慧路灯&#xff0c;作为智慧城市、新基建、城市更新的主要组成部分&#xff0c;近些年在各大城市已得到很好的落地和 应用&#xff0c;但其与传统路灯相比集成大量异元异构电子设备&#xff0c;这些设备的供电电压、接口形式、权属单位各不相同&#xff0c; 如何设计一…

《绝地求生》职业选手画面设置推荐 绝地求生画面怎么设置最好

《绝地求生》画面怎么设置最好是很多玩家心中的疑问&#xff0c;如果性能不是问题无疑高特效显示效果更好&#xff0c;但并不是所有画面参数都利于战斗&#xff0c;今天闲游盒带来分享的《绝地求生》职业选手画面设置推荐&#xff0c;赶紧来看看吧。 当前PUBG的图像设置的重要性…

YOLOv5改进 | 主干篇 | 12月份最新成果TransNeXt特征提取网络(全网首发)

一、本文介绍 本文给大家带来的改进机制是TransNeXt特征提取网络,其发表于2023年的12月份是一个最新最前沿的网络模型&#xff0c;将其应用在我们的特征提取网络来提取特征&#xff0c;同时本文给大家解决其自带的一个报错&#xff0c;通过结合聚合的像素聚焦注意力和卷积GLU&…