首页 > 其他分享 >数位 dp

数位 dp

时间:2025-01-23 11:12:20浏览次数:1  
标签:01 数字 P2602 例题 dp 数位

首先看一道例题 

Example 01 [P2602 数字统计]
求 [l,r] 中每个数字出现了多少次
(1 <= l,r <= 1e12)

Solution 
这题直接 for 肯定会 TLE
我们思考用一个 dp 数组
dp[i][j][k] 表示搜到第 i 位,保证最高位为 j,数字 k 的出现次数
(比如 dp[2][1][1] 就表示 [0,19] 有多少个 1) 
显然区间比较难
我们借用前缀和思想
将 ans[l,r] 转化为 ans[1,r]-ans[1,l-1] 即可

首先得到一个方程 
dp[i][j][k] 是 [j...00~j...99]中 k 的次数
所以 dp[i][j][k] = 所有 j 中 k 出现次数 + [000000000~999999999] 中 k 出现次数
				 = 所有 j 中 k 出现次数 + sum(dp[i-1][iterator][k]) [0~9] 
				 
现在我们只差第一部分怎么求 
如果 j!=k 第一部分肯定是 0
否则就是   1e(i-1) 
所以完整版的转移方程即为

dp[i][j][k]={ sum(dp[i-1][iterator][k]) [0~9]              (j!=k)
			{ 1e(i-1) + sum(dp[i-1][iterator][k]) [0~9]    (j==k)

这个肯定是能求的
于是有如下 Code

const unsigned long long ten[16]={1,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13,1e14,1e15};
unsigned long long number[16][11][11]; 
void _memset(){
	//明显如果只有 0 位,那么一定只有 0 个 
	for(int i=0;i<=9;i++)number[1][i][i]=1;//初始化状态 
	for(int i=2;i<=13;i++)for(int j=0;j<=9;j++)for(int k=1;k<=9;k++){//枚举 i,j,k 
		if(j==k)number[i][j][k]+=ten[i-1];		
		for(int it=0;it<=9;it++)number[i][j][k]+=number[i-1][it][k];
	} 
} 

这部分非常简单
接下来考虑如何求解
比如说 6187
首先我们拆开每一位,变成 6 0 8 7 (C++ 语法入门) 
接下来统计三种
# 01 位数与原数一样,高位较小的数 (for 循环使用) 
ans+=[1000,1999]+[2000,2999]+[3000,3999]+[4000,4999]+[5000,5999] 
# 02 位数较小,无前导零 (for 循环使用) 
ans+=[0]+...+[9]+[10,19]+[20,29]+....+[900,999] 

我们发现已经将 [0,5999] 的 ans 统计完了 
还差 [6000,6187] 
接下来我们直接将区间拆开
[6000,6099]
[6100,6109]+[6110,6119]+...+[6170,6179]
[6180]+[6181]+...+[6187]
我们再将每个区间劈开
k*[60]+[00,99]
k*[610]+[0,9]+k*[611]+[0,9].......
.....
(太抽象了)
一波玄学统计,然后就结束了
 
于是太离谱了,还是开码吧

Code 

标签:01,数字,P2602,例题,dp,数位
From: https://www.cnblogs.com/2025ing/p/18687362

相关文章

  • 【做题记录】2025提高刷题-dp
    A.Min-FundPrison(Medium)考虑一个边双连通分量一定不可能分为合法的两部分,于是进行缩点。缩完后显然是一个森林。设\(dp_{i,j,0/1}\)表示第一堆有\(i\)个点,第二堆有\(j\)个点,两堆点有没有用一条边连起来的最小花费。对于每棵树,考虑将它加入第一堆/加入第二堆/一部分加......
  • 实数域上的DP?——[AGC020F] Arcs on a Circle
    #实数域上的DP?——[AGC020F]ArcsonaCircle有点没搞懂。---注意到线段长度为整数,即li和ri的小数部分一定相同而判断两个线段是否相交只会用到l和r的相对大小关系,所以可以对小数部分离散化然后就可以dp了。先断环为链,$n!$暴力枚举小数部分相对大小,离散化以后一共......
  • 【SAP Abap】X档案:SAP ABAP 中 AMDP 简介及实现方法(转)
    SAPABAP中AMDP简介及实现方法0、前言1、AMDP简介1.1代码下沉(CodePushdown)1.2AMDP是托管数据库过程的容器1.3AMDP的优缺点1.4几种数据库访问方式的区别1.5几种数据库访问方式的选用1.6使用的开发工具2、实现方法2.1AMDPPROCEDURE(存储过程)实现2.2AMDPFUNCTION(函数......
  • 解释下什么是PPI和DP?
    PPI和DP是前端开发中经常遇到的两个概念,尤其在移动端和响应式设计中更为重要。下面是对这两个概念的详细解释:PPI(PixelsPerInch):定义:PPI,即像素密度,指的是每英寸屏幕上显示的像素数量。它是衡量屏幕显示细腻程度的一个重要指标。计算方法:PPI的计算公式是屏幕对角线上的像素......
  • 高频次UDP 小包丢包分析
    目录背景测试方法测试结果case1:(经过多级交换机)case2:长时测试(经过多级交换机)case3:长时测试(设备直联)可能原因分析解决方法背景UDP作为面向非连接的传输协议,并不能保证可靠交付。本文编写代码测试设备之间UDP小包传输的可靠性。测试方法发送侧基于......
  • 凸性 DP 优化
    首先这里点名\(\rmWQS\)二分还有决策单调性,但是今天就不写这个了,今天学了一些进阶的东西。闵可夫斯基和这个东西时是用来优化一类凸函数卷积的,一般就是背包或者分治时使用。最常用的是\((\max/\min,+)\)卷积。首先考虑这个卷积式:\(f_k=\max_{i+j=k}\{g_i+h_j......
  • 【Azure APIM】APIM服务配置网络之后出现3443端口不通,Management Endpoint不健康状态
    问题描述APIM服务在配置网络之后,查看网络状态发现ManagementEndpoint是不健康状态,提示无法连接到3443端口。错误消息:Failedtoconnecttomanagementendpointatxxxxxxxx.management.azure-api.cn:3443foraservicedeployedinavirtualnetwork.Makesuretofollo......
  • 分治优化DP
    分治优化DPLink\(\text{Para.1}\hspace{0.2cm}\)四边形不等式对于形如\(\text{dp}[i][j]=\min_{k<j}{\text{dp}[i-1][k]+\text{cost}[k+1][j]}\)的形式,若\(\text{cost}\)满足\(\text{cost}[a][c]+\text{cost}[b][d]\leq\text{cost}[a][d]+\text{cost}[b......
  • 【计算机网络】传输层协议TCP与UDP
    传输层    传输层位于OSI七层网络模型的第四层,主要负责端到端通信,可靠性保障(TCP),流量控制(TCP),拥塞控制(TCP),数据分段与分组,多路复用与解复用等,通过TCP与UDP协议实现。端到端通信    传输层通过端口号(Port)来区分不同进程。端口号为16位数字(0-65535),用于标......
  • Github开源项目源码阅读(progschjThreadPool)
    项目地址:https://github.com/progschj/ThreadPool项目源码:#ifndefTHREAD_POOL_H#defineTHREAD_POOL_Hinclude<vector>include<queue>include<memory>include<thread>include<mutex>include<condition_variable>include<f......