首页 > 其他分享 >数位统计DP——AcWing 338. 计数问题

数位统计DP——AcWing 338. 计数问题

时间:2024-06-21 10:59:50浏览次数:14  
标签:10 338 int res num 计数问题 数位 DP 数字

数位统计DP

定义

数位DP(Digital DP)是一种用于解决与数字的数位相关问题的动态规划算法。它将数字的每一位看作一个状态,通过转移状态来计算满足特定条件的数字个数或其他相关统计信息。

运用情况

  • 统计满足特定条件的数字个数,例如在给定范围内有多少个数字满足某些数位特征。
  • 计算数字的某个数位上的特定统计信息,如出现的数字频率等。
  • 解决与数字排列、组合相关的问题。

注意事项

  1. 数位DP的核心是正确定义状态和状态转移方程。状态的设计要能够简洁地表示问题的特征,并且状态转移要能够准确地反映数字的数位变化。
  2. 注意边界情况的处理,特别是对于最高位和最低位的特殊处理。
  3. 数位DP通常需要进行记忆化搜索或使用动态规划数组来避免重复计算,以提高效率。
  4. 在实际应用中,要根据具体问题的特点选择合适的数位DP方法,并进行适当的优化和剪枝。

解题思路

  • 分析问题,确定需要统计的数字特征或满足的条件。
  • 设计状态,通常使用一个多维数组来表示不同数位上的状态。
  • 定义状态转移方程,描述如何从一个状态转移到另一个状态。
  • 确定初始状态和边界条件。
  • 使用记忆化搜索或动态规划算法来计算状态值。
  • 根据最终的状态值得到问题的答案。

AcWing 338. 计数问题

题目描述

AcWing 338. 计数问题 - AcWing

运行代码

#include <iostream>
#include <vector>
using namespace std;
int power(int x)
{
    int res = 1;
    while(x --) 
res *= 10;
    return res;
}
int get(vector<int> num, int l, int r)
{
    int res = 0;
    for(int i = l; i >= r; i -- ) res = res * 10 + num[i];
    return res;
}
int count(int n, int x)
{
    if(n == 0) return 0;
    vector<int> num;
    while(n)
    {
        num.push_back(n%10);
        n/=10;
    }
    n = num.size();
    int res = 0;
    for(int i = n - 1 - !x; i >= 0; i --)
    {
        if(i < n - 1)
        {
            res += get(num, n - 1, i + 1) * power(i);
            if(x == 0) res -= power(i);
        }
        if(num[i] == x) res += get(num, i - 1, 0) + 1;
        else if(num[i] > x) res += power(i);
    }
    return res;
}
int main()
{
    int a, b;
    while(cin >> a >> b, a && b)
    {
        if(a > b) swap(a, b);
        for(int i = 0; i < 10; i ++)
            cout << count(b, i) - count(a - 1, i) << ' ';
        cout << endl;
    }
    return 0;
}

代码思路

  • power 函数:计算 10 的指定次幂。
  • get 函数:从给定的数字数组中,按照指定的范围(从左到右)提取出一个数字。
  • count 函数:这是核心函数,用于计算给定数字 n 中特定数字 x 出现的次数。它通过将数字 n 转换为数字数组,然后从高位到低位进行分析计算。对于每一位,如果该位小于最高位且不等于 x,则加上前面高位构成的数字乘以 10 的相应次幂;如果该位等于 x,则加上低位数字构成的数加 1;如果该位大于 x,则加上 10 的相应次幂。最后返回总的出现次数。
  • 在 main 函数中:不断读取两个数字 a 和 b,如果都不为 0 则进行处理。通过交换确保 a 小于 b,然后对于数字 0 到 9,分别计算在 b 中出现的次数减去在 a-1 中出现的次数,并输出。

改进思路

  1. 简化计数逻辑:当前的count函数实现较为复杂,它通过手动处理每一位数字来统计特定数字x出现的次数。可以考虑简化这一过程,直接遍历范围内的每个数,统计相应数字出现的次数,这可能使逻辑更清晰。

  2. 避免重复计算:注意到count函数对每个数字xab都独立计算了一次,这导致了很多重复的工作,特别是对于连续的整数序列。可以通过计算每个数字在一个数位上的贡献,然后根据位数累加这些贡献,来减少重复计算。

  3. 使用字符串处理数字:将整数转换成字符串处理,在某些情况下可以使代码更加直观简洁,尤其是在需要频繁操作数字的每一位时。

  4. 预计算 powers of 10:当前power10函数在每次调用时都重新计算10的幂,如果在循环外预先计算好所需的10的幂次方数组,可以提高效率。

  5. 优化输入处理:代码中通过if(a > b) swap(a, b);确保了a<=b,但这个条件检查对于解决问题并非必要,因为统计数字出现的次数并不依赖于a和b的顺序。

  6. 利用STL中的容器和算法:比如,可以使用std::unordered_map来存储每个数字出现的次数,利用标准库提供的函数来简化代码。

标签:10,338,int,res,num,计数问题,数位,DP,数字
From: https://blog.csdn.net/u014114223/article/details/139814974

相关文章

  • Manifest V3 getBackgroundPage() 返回 undefined 或报错 You do not have a backgrou
    省流:无解了,老老实实 sendMessage罢这件事挺奇怪的,因为我看官方文档就是这么写的,也没什么特别说明,版本也是最新的,就挺奇怪的……在翻了一大圈,之后看到了这篇帖子:意思就是说,api已经不能用了,文档因为人手不够就没更新…… 此外还有一个 chrome.runtime.getBackgroundPage......
  • TCP与UDP详解:层次、区别及应用场景
    TCP和UDP的层次及区别详解所属层次TCP(TransmissionControlProtocol,传输控制协议)和UDP(UserDatagramProtocol,用户数据报协议)都属于OSI模型中的传输层(第四层)。在传输层,协议的主要作用是为端到端的通信提供逻辑通信,并确保数据在网络上传输的可靠性和顺序。TCP和UDP的区别......
  • api-ms-win-shcore-scaling-l1-1-1.dll解析及缺失解决策略:确保Windows高DPI显示正常
    api-ms-win-shcore-scaling-l1-1-1.dll是Windows操作系统中的一个API接口库文件,属于WindowsShellCommonDLLs(Shell核心动态链接库)的一部分。这个特定的DLL文件与Windows的高DPI(每英寸点数)缩放功能紧密相关,支持应用程序在不同分辨率和缩放设置下正确显示界面元素,确保UI的清晰......
  • hdu2845dp问题
    看了一眼题目,简单dp问题,但超时了一晚上,试了各种方法无法解决,最终放弃java,改用C直接过,我哭了。。。。#include<stdio.h>#include<string.h>#definemaxn200010intdp[maxn],ans[maxn],map[maxn];intmax(intx,inty){returnx>y?x:y;}intmain(){inti,j;......
  • MPC与DDP结合案例
    MPC与DDP结合概要MPC与DDP的关系1.相似性:优化过程:都涉及到优化一个代价函数以求得最优控制输入。动态模型:都依赖于系统的动力学模型来预测和更新系统状态。2.差异性:时间尺度:MPC是在线控制,每次只优化有限预测区间的控制输入,然后在每个时间步长重新优化。......
  • dp题选做
    1.在两个数列之间有两个整数数列\(a_1,a_2,\cdots,a_n\)和\(b_1,b_2,\cdots,b_n\)。我们的任务是找出满足以下条件的数列\(c_1,c_2,\cdots,c_n\):对\(i=1,2,\cdots,n\),\(a_i\lec_i\leb_i\)对\(i=1,2,\cdots,n-1\),\(c_i\lec_{i+1}\)所有\(c_i\)都是整数满足这......
  • 计数类DP——AcWing 900. 整数划分
    计数类DP定义计数类DP主要是通过动态规划的方法来计算满足特定条件的方案数、组合数等数量相关的问题。运用情况需要计算不同排列、组合或情况的数量。问题具有明显的阶段性,且每个阶段的选择会对后续阶段产生影响。可以通过逐步构建较小规模问题的解来推导出大规模问题的解......
  • 揭秘ThreadPoolExecutor:深度解析Java线程池的艺术与源码之美
    1.线程池概述在Java中,线程池(ThreadPool)是一种管理线程的技术,通过预先创建并管理一组线程,来减少频繁创建和销毁线程所带来的开销,从而提高系统的响应速度和吞吐量。ThreadPoolExecutor是Java并发包java.util.concurrent中的一个核心类,它提供了丰富的线程池功能。2.Thread......
  • DPDK 关闭网口速率自动协商, 强制网口速率
    dpdk源码中的宏定义#defineETH_LINK_SPEED_FIXED(1<<0)//<Disableautoneg(fixedspeed)#defineETH_LINK_SPEED_10M_HD(1<<1)//<10Mbpshalf-duplex....要查看设备的支持速度能力,您可以调用rte_eth_dev_info_get,例如rte_eth_dev_info_get(port......
  • 项目运维时,某用户通过RDP远程桌面连接服务器...任务管理器显示用户状态断开连接!记录运
    目录问题出现解决方式测试参考  今天处理项目运维问题,发现服务器任务管理器出现用户状态断开连接......问题出现项目运维时,某用户通过rdp远程桌面连接Windowsserver服务器时,出现服务器发布的进度计划无法执行,打开服务器任务管理界面出现用户状态断开连接标志,如下......