【C++动态规划 数位dp】2376. 统计特殊整数|2120

embedded/2024/12/26 1:07:57/

本文涉及知识点

下载及打开打包代码的方法兼述单元测试
C++动态规划 数位dp

LeetCode2376. 统计特殊整数

如果一个正整数每一个数位都是 互不相同 的,我们称它是 特殊整数 。
给你一个 正 整数 n ,请你返回区间 [1, n] 之间特殊整数的数目。
示例 1:
输入:n = 20
输出:19
解释:1 到 20 之间所有整数除了 11 以外都是特殊整数。所以总共有 19 个特殊整数。
示例 2:
输入:n = 5
输出:5
解释:1 到 5 所有整数都是特殊整数。
示例 3:
输入:n = 135
输出:110
解释:从 1 到 135 总共有 110 个整数是特殊整数。
特殊的部分数字为:22 ,114 和 131 。
提示:
1 <= n <= 2 * 109

动态规划数位dp

自定义状态:mask ∈ \in [0,1 << 10),mask&(1<<j) 表示数字j是否使用。

代码

核心代码

template<class ELE, class ResultType, ELE minEle, ELE maxEle>
class CLowUperr
{
public:CLowUperr(int iCustomStatusCount) :m_iCustomStatusCount(iCustomStatusCount){}void Init(const ELE* pLower, const ELE* pHigh, int iEleCount){m_vPre.assign(4, vector<ResultType>(m_iCustomStatusCount));if (iEleCount <= 0){return;}InitPre(pLower, pHigh);iEleCount--;while (iEleCount--){pLower++;pHigh++;vector<vector<ResultType>> dp(4, vector<ResultType>(m_iCustomStatusCount));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 Sum(int iMinMask,int iMaxMask)const{ResultType iRet = 0;for (int status = 0; status < 4; status++){for (int mask = iMinMask; mask <= iMaxMask; mask++){iRet += m_vPre[status][mask];}}return iRet;}
protected:const int m_iCustomStatusCount;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;
private: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);}}};class CCharLowerUper : public CLowUperr<char, int, '0', '9'>{public:using CLowUperr<char, int, '0', '9'>::CLowUperr;int Total(){		int ans = 0;for (const auto& v : m_vPre) {ans += accumulate(v.begin(), v.end(), 0);}return ans;}protected:virtual void OnEnumFirstBit(vector<int>& vPre, const char curValue){const int index = curValue - '0';vPre[1<<index]++;}virtual void OnEnumOtherBit(vector<int>& dp, const vector<int>& vPre, char curValue){const int index = curValue - '0';for (int i = 0; i < vPre.size(); i++) {if (i & (1 << index)) { continue; }dp[i | (1 << index)] += vPre[i];}			}};class Solution {public:int countSpecialNumbers(int n) {string str = to_string(n);const int len = str.length();int ans = 0;for (int i = 1; i <= len; i++) {CCharLowerUper lu(1<<10);string strlower = "1" + string(i - 1, '0');string strUp = (len == i) ? str : string(i, '9');lu.Init(strlower.c_str(), strUp.c_str(), i);ans += lu.Total();}return ans;}};int n;

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。


http://www.ppmy.cn/embedded/148759.html

相关文章

完全二叉树的权值(蓝桥杯2019年试题G)

给定一棵包含N个节点的完全二叉树&#xff0c;树上的每个节点都有一个权值&#xff0c;按从上到小、从左到右的顺序依次是A1、A2……An,&#xff08;1&#xff0c;2&#xff0c;n为下标。&#xff09;如下图所示。 现在&#xff0c;小明要把相同深度的节点的权值加到一起&#…

uniapp小程序使用webview 嵌套 vue 项目

uniapp小程序使用webview 嵌套 vue 项目 小程序中发送 <web-view :src"urlSrc" message"handleMessage"></web-view>export default {data() {return {urlSrc: "",};},onLoad(options) {// 我需要的参数比较多 所以比较臃肿// 获取…

ROSboard:为您的机器人提供强大的Web可视化工具

ROSboard&#xff1a;为您的机器人提供强大的Web可视化工具 rosboard ROS node that turns your robot into a web server to visualize ROS topics [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/ro/rosboard 项目介绍 ROSboard 是一个专为机器人设计的 Web 服…

【C++基础】09、结构体

一、结构体(struct) C/C 数组允许定义可存储相同类型数据项的变量&#xff0c;但是结构体是 C 中另一种用户自定义的可用的数据类型&#xff0c;它允许存储不同类型的数据项。 结构体用于表示一条记录&#xff0c;假设现在想要跟踪图书馆中书本的动态&#xff0c;可能需要跟踪每…

AIDD - 人工智能药物设计 - 在 Docker 上创建和运行 PostgreSQL + RDKit 卡带环境

在 Docker 上创建和运行 PostgreSQL RDKit 卡带环境 背景 我们将讨论化学数据库。 看起来&#xff0c;如果你在 PostgreSQL 中放置一个 RDKit cartridge &#xff08;扩展&#xff09;&#xff0c;就可以基于 SQL 进行结构相似性搜索&#xff0c;看起来很有趣。但是我找不到…

【故障处理系列--gitlab的CI流水线下载安装包提示报错】

故障现象&#xff1a; 前端同事一直向我反映使用alpine-node系列的镜像&#xff0c;安装包报错故障原因 在CI文件上配置的代理没有生效&#xff0c;导致流水线无法在gitlab-runner上拉取https://registry.npmmirror.com仓库软件包 后来查资料提示说&#xff0c;在gitlab的CI文…

JMeter 二次开发之环境准备

通过JMeter二次开发&#xff0c;可以充分发挥JMeter的潜力&#xff0c;定制化和扩展工具的能力以满足具体需求。无论是开发自定义插件、函数二次开发还是定制UI&#xff0c;深入学习和掌握JMeter的二次开发技术&#xff0c;将为接口功能测试/接口性能测试工作带来更多的便利和效…

Python中所有子图标签Legend显示详解

在数据可视化中&#xff0c;图例&#xff08;legend&#xff09;是一个非常重要的元素&#xff0c;它能够帮助读者理解图表中不同元素的含义。特别是在使用Python进行可视化时&#xff0c;matplotlib库是一个非常强大的工具&#xff0c;能够轻松创建包含多个子图的图表&#xf…