C++数位动态规划算法:统计整数数目
题目
给你两个数字字符串 num1 和 num2 ,以及两个整数 max_sum 和 min_sum 。如果一个整数 x 满足以下条件,我们称它是一个好整数:
 num1 <= x <= num2
 min_sum <= digit_sum(x) <= max_sum.
 请你返回好整数的数目。答案可能很大,请返回答案对 109 + 7 取余后的结果。
 注意,digit_sum(x) 表示 x 各位数字之和。
 示例 1:
 输入:num1 = “1”, num2 = “12”, min_num = 1, max_num = 8
 输出:11
 解释:总共有 11 个整数的数位和在 1 到 8 之间,分别是 1,2,3,4,5,6,7,8,10,11 和 12 。所以我们返回 11 。
 示例 2:
 输入:num1 = “1”, num2 = “5”, min_num = 1, max_num = 5
 输出:5
 解释:数位和在 1 到 5 之间的 5 个整数分别为 1,2,3,4 和 5 。所以我们返回 5 。
 提示:
 1 <= num1 <= num2 <= 1022
 1 <= min_sum <= max_sum <= 400
分析
a. 先考虑数位相等
DoSameLen函数处理数位相等。用动态规划,假定已经处理了i位,正在处理第i位。对于某种状态,我们只关心:一,位数和,取值范围[0, max_sum],共max_sum+1种,大于max_sum的状态抛弃。二,上下界。非边界、上边界、下边界、上下界。如:num1=”121”,num2=”142”则”1”是上下界,"12"是下界,"13"是非边界、"14"是上边界。如果上下界,则当前位只能取值[num1[i],nums2[i]]。如果上边界,则只能取值[0,nums2[i]]。如果是下边界,则能取[nums1[i],9]。如果是非边界,则可以任意取值。
| 前一轮状态 | 当前条件 | 新状态 | 
|---|---|---|
| 上下界 | 同时等于num1[i]和num2[i] | 上下界 | 
| 上下界 | 等于num1[i] | 下界 | 
| 上下界 | 等于num2[i] | 上界 | 
| 上下界 | num1[i]和num2[i]之间 | 非边界 | 
| 上界 | 等于num2[i] | 上界 | 
| 上界 | 小于num2[i] | 非边界 | 
| 下界 | 等于num1[i] | 下界 | 
| 下界 | 大于num1[i] | 非边界 | 
| 非边界 | 0到9 | 非边界 | 
b. 优化掉上下界
上下界一定出现再最前面,且数量为1。当i为0时,有新的上下界,那说明num1[0]和num2[i],只能选择num1[i]。当i大于0是,有新的上下界,那么num1[i]等于num2[i],由于(i-1)也是上下界,所有num1和num2的前i+1个元素相同。由于第i为只能num1[i],所以数量不变。
 假定num1和num2的前i位完全相同,则前i位只有一个合法数。
 这意味这num1和num2扔掉相同的前者,边界状态的数量不变。比如:
 num1 = “112”和num2 = “115”, 下界:115,非边界:113和114 上界:115。
 num1 = “12”和num2 = “15”, 下界:15,非边界:13和14 上界:15。
 num1 = “2”和num2 = “5”, 下界:5,非边界:3和4 上界:5。
c. 考虑数位不等
假定num1的长度为l1,num2的长度为l2,则分别:
 Do(num1,string(l1,’9’)
 for(int i = l1+1; i < l2 ;i++)
 {
 Do(‘1’+string(i-1,’0’),string(i,’9’);
 }
 Do(‘1’+string(i2-1,’0’),num2)
 比如:
 nums1 = “1”,nums2=”19”
 Do(“1”,”9”)
 Do(“10”,”19”)
 再如:
 nums1 = “1”,nums2=”123”
 Do(“1”,”9”)
 Do(“10,”99”)
 Do(“100,”123”)
 注意:
 l1等于l2时要分别处理。
核心代码
class Solution {
 public:
 int count(string num1, string num2, int min_sum, int max_sum) {
 m_min_sum = min_sum;
 m_max_sum = max_sum;
 const int l1 = num1.length();
 const int l2 = num2.length();
 if (l1 == l2)
 {
 return DoSameLen(num1, num2).ToInt();
 }
 C1097Int biRet;
 biRet += DoSameLen(num1, string(l1, ‘9’));
 for (int i = l1 + 1; i < l2; i++)
 {
 biRet += DoSameLen(“1” + string(i - 1, ‘0’), string(i,‘9’));
 }
 biRet += DoSameLen(“1” + string(l2-1,‘0’), num2);
 return biRet.ToInt();
 }
 C1097Int<> DoSameLen(string num1, string num2)
 {
 int n = num1.size();//只处理相等位数
 int i = 0;
 int sum = 0;
 for (; (i < n) && (num1[i] == num2[i]); i++)
 {
 sum += num1[i] - ‘0’;
 }
 if (i >= n)
 {
 return ((sum >= m_min_sum)&&( sum <= m_max_sum)) ? 1 : 0;
 }
 //注[1]
 vector<vector<C1097Int<>>> pre(3, vector<C1097Int<>>(m_max_sum+1));
 Set(pre, 1, sum + num1[i]-‘0’, 1);
 for (int j = num1[i] + 1; j < num2[i]; j++)
 {
 Set(pre, 0, sum +j - ‘0’, 1);
 }
 Set(pre, 2, sum + num2[i] - ‘0’, 1);
 for (i++; i < n; i++)
 {
 vector<vector<C1097Int<>>> dp(3, vector<C1097Int<>>(m_max_sum + 1));
 for (int preSum = 0; preSum <= m_max_sum; preSum++)
 {
 //处理下界
 Set(dp, 1, preSum + num1[i] - ‘0’, pre[1][preSum]);
 for (int j = num1[i] + 1; j <= ‘9’; j++)
 {
 Set(dp, 0, preSum + j - ‘0’, pre[1][preSum]);
 }
 //处理无边界
 for (int j = ‘0’; j <= ‘9’; j++)
 {
 Set(dp, 0, preSum + j - ‘0’, pre[0][preSum]);
 }
 //处理上界
 for (int j = ‘0’; j < num2[i]; j++)
 {
 Set(dp, 0, preSum + j - ‘0’, pre[2][preSum]);
 }
 Set(dp,2, preSum + num2[i] - ‘0’, pre[2][preSum]);
 }
 pre.swap(dp); 
 }
 return Cal(pre);
 }
 void Set(vector<vector<C1097Int<>>>& dp, int status, int sum,C1097Int<> iAddNum)
 {
 if (sum > m_max_sum)
 {
 return;
 }
 dp[status][sum] += iAddNum;
 }
 C1097Int<> Cal(const vector<vector<C1097Int<>>>& pre)
 {
 C1097Int<> biRet;
 for (int i = 0; i < 3; i++)
 {
 for (int j = m_min_sum; j <= m_max_sum; j++)
 {
 biRet += pre[i][j];
 }
 }
 return biRet;
 }
 int m_min_sum, m_max_sum;
 };
测试代码
int main()
 { 
 int res = 0;
 res = Solution().count(“2”, “5”, 0, 100);
 assert(res == 4);
 res = Solution().count(“12”, “15”, 0, 100);
 assert(res == 4);
 res = Solution().count(“112”, “115”, 0, 100);
 assert(res == 4);
 res = Solution().count(“112”, “115”, 5, 100);
 assert(res == 3);
 res = Solution().count(“112”, “115”, 0, 6);
 assert(res == 3);
 res = Solution().count(“112”, “115”, 5, 6);
 assert(res == 2);
 res = Solution().count(“1”, “12”, 1, 8);
 assert(res == 11);
CConsole::Out(res);
}
 
其它
视频课程
如果你觉得复杂,想从简单的算法开始,可以学习我的视频课程。
 https://edu.csdn.net/course/detail/38771
 我的其它课程
 [https://edu.csdn.net/lecturer/6176]
(https://edu.csdn.net/lecturer/6176)
测试环境
win7 VS2019 C++17
相关下载
算法精讲《闻缺陷则喜算法册》doc版
 https://download.csdn.net/download/he_zhidan/88348653

相关文章:
 
C++数位动态规划算法:统计整数数目
题目 给你两个数字字符串 num1 和 num2 ,以及两个整数 max_sum 和 min_sum 。如果一个整数 x 满足以下条件,我们称它是一个好整数: num1 < x < num2 min_sum < digit_sum(x) < max_sum. 请你返回好整数的数目。答案可能很大&…...
ip 网段设置 --chatGPT
问:host all all 127.0.0.1/32 scram-sha-256 里的 127.0.0.1/32 是什么含义 ,要指定某个呢 gpt: 在 PostgreSQL 的 pg_hba.conf 文件中,127.0.0.1/32 是一个用于定义访问控制规则的CIDR(无类域间路由)标记࿰…...
 
使用JMeter进行接口测试教程
安装 使用JMeter的前提需要安装JDK,需要JDK1.7以上版本目前在用的是JMeter5.2版本,大家可自行下载解压使用 运行 进入解压路径如E: \apache-jmeter-5.2\bin,双击jmeter.bat启动运行 启动后默认为英文版本,可通过Options – Cho…...
文本生成解码策略
解码策略 1. sample实现了怎样的功能 不是直接选择概率最大的token,而是根据多项式分布进行采样获得下一个token 这里的概率通过设置一些策略,进行处理。例如,解码最小长度(当长度小于该值的时候,eos的采样概率为0&am…...
 
华为数通方向HCIP-DataCom H12-831题库(单选题:221-240)
第221题 以下关于IS-IS的LSP分片功能的描述,正确的是哪一项? A、IS-IS的分片扩展功能的Mode-1模式,虚拟系统是需要参与路由SPF计算的 B、IS-IS的LSP分片功能,是用于让收到LSP分片报文的设备老化相关路由信息 C、IS-IS的分片扩展功能,是通过LSP报文中的LSPID实现的 D、IS-…...
AttributeError: module ‘hanlp.utils.rules‘ has no attribute ‘tokenize_english‘
附原文链接:http://t.csdnimg.cn/wVLib import hanlp tokenizer hanlp.utils.rules.tokenize_english tokenizer(Mr. Hankcs bought hankcs.com for 1.5 thousand dollars.) 改为: from hanlp.utils.lang.en.english_tokenizer import tokenize_eng…...
 
苍穹外卖(四) AOP切面公共字段自动填充及文件上传
一.AOP切面公共字段填充 问题分析 如果都按照上述的操作方式来处理这些公共字段, 需要在每一个业务方法中进行操作, 编码相对冗余、繁琐,那能不能对于这些公共字段在某个地方统一处理,来简化开发呢? 答案是可以的,我们使用AOP切…...
vue-cli + vue3 项目 ios 苹果手机白屏问题
目录 问题描述原因分析解决方案遇到的坑1,架构问题2,项目引入其他依赖的问题 参考 问题描述 vue-cli vue3 的项目,在苹果手机上打开白屏,安卓手机正常显示。 原因分析 1,借助 vconsole 发现并没有打印报错信息&…...
 
Spring Boot中的JdbcTemplate是什么,如何使用
Spring Boot中的JdbcTemplate是什么,如何使用 Spring Boot是一个流行的Java应用程序开发框架,它简化了Java应用程序的开发过程,并提供了丰富的功能和工具。在Spring Boot中,JdbcTemplate是一个强大的数据库访问工具,它…...
Python测网络连通性、能否访问某个网络或者端口号<网络检测、ping主机、测试端口>
一、ping命令及其使用 ping命令是在计算机网络领域中用来测试目标主机是否可达以及其延迟时间的命令。对于Python来说,我们可以通过subprocess模块来实现执行命令。下面是示例代码: import subprocessdef ping(host):result subprocess.run([ping, -c…...
 
【沧元图】玉阳宫主是正是邪,和面具人有勾结吗?现在已有答案了
Hello,小伙伴们,我是小郑继续为大家深度解析沧元图。 沧元图这部动漫中,有一个很特殊的人物,也是一个让人看不透的人物,因为很多人都不知道这个人是正还是邪,这个人就是玉阳宫主。 因为这个人明面上是掌管东宁府维护东…...
 
C++笔记之popen()和std_system()和std_async()执行系统命令比较
C笔记之popen()和std_system()和std_async()执行系统命令比较 code review! 文章目录 C笔记之popen()和std_system()和std_async()执行系统命令比较1.popen()2.std::system()3.std::async()——C11提供的异步操作库,适合在多线程中执行外部命令,建议使…...
 
pycharm2020无法打开,点击无反应
pycharm 2020 无法打开,点击无反应,今天我碰到这现象,总结大体原因 C:\Users\ygw\AppData\Roaming\JetBrains (删除该目录即可,一般由于升级安装 或 安装两个不同版本 会存在老旧文件影响导致)...
 
深度学习之微调
在现代深度学习领域,精细调整(Fine-tune)已经成为一种非常重要的技术手段。 预训练模型 在介绍finetune之前,先了解一下什么是预训练模型。在搭建一个网络模型来完成一个特定的图像分类的任务时,首先,需要…...
【# 完美解决 node.js 模块化后报错 ReferenceError: require is not defined】
完美解决 node.js 模块化后报错 ReferenceError: require is not defined 错误信息如图 直接改插件源码:(不是cnpm里的插件,而是下载下来的export2Excel.js) 在export2Excel.js内只要改动头部一行源码即可 改之前:…...
Jackson忽略json数组中null元素
问题 前端传过来的json字符串中,其中json数组包含null字符。类型如下: ["0","1","2",null]这边Spring使用Jackson进行反序列化是会出现List对象中,包含null的数组元素。即List大小为4,本来List的…...
 
基于SpringBoot的网上订餐系统
基于SpringBoot的网上订餐系统的设计与实现 开发语言:Java数据库:MySQL技术:SpringBootMyBatisVue工具:IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色:用户、管理员管理员:登录、个人中心、会员管理、…...
【04】基础知识:React组件实例三大核心属性 - state
一、state 了解 理解 1、state 是组件对象最重要的属性,值是对象(可以包含多个 key-value 的组合) 2、组件被称为 “状态机”, 通过更新组件的 state 来更新对应的页面显示(重新渲染组件) 强烈注意 1、…...
 
SpringBoot 过滤器filter当中的自定义异常捕获问题
需求描述:需要根据用户的请求路径拦截做权限控制: 但是这样做全局异常无法捕获 解决方案: 在filter当中引入HandlerExceptionResolver类,通过该类的resolveException方法抛出自定义异常: public class OpenInvokeFil…...
 
实验3:左右循环LED灯
获取流水灯工程: 方式一: keilproteus 完成最小系统,点亮led 灯实验_吴小凹的博客-CSDN博客 方式二: Flowing_led.zip - 蓝奏云直接下载。 原理图修改: 无须修改只需要使用流水灯的工程即可,解压到桌面…...
 
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
 
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
 
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
在Spring Boot中集成RabbitMQ的完整指南
前言 在现代微服务架构中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件,支持多种消息协议,具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...
 
MLP实战二:MLP 实现图像数字多分类
任务 实战(二):MLP 实现图像多分类 基于 mnist 数据集,建立 mlp 模型,实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入,可视化图形数字; 2、完成数据预处理:图像数据维度转换与…...
