首页 > 其他分享 >数位 dp 学习心得

数位 dp 学习心得

时间:2023-10-13 14:22:40浏览次数:33  
标签:10 数字 int ll 学习心得 len 前导 dp 数位

感觉非常牛逼。最牛逼的是很多情况下要去掉前导零。

去掉前导零的方法通常是先忽略前导零的约束,最后再容斥掉有多少0。

Luogu P2602 数字计数

来自【详细解释】数字计数 ZJOJ p2602 一道练习数位DP的好题 - moye到碗里来 的博客 - 洛谷博客 (luogu.com.cn)

那么我们首先看题,对于这道题我一开始以为很水,但是当我仔细去读题之后发现事情没那么简单。其中对于这道题(递推做法)最大的难点是难以找出递推式子(废话,你写递推就只有这点难了)。为啥,因为你很难想到怎样求出第几位它的数字又多少,因为不能有前导0。但是我们发现如果不考虑是否有前导0的话,那么这道题就似乎有递推公式。

\(f[i]\) 代表在有 i 位数字的情况下,每个数字有多少个。如果不考虑前导0,你会发现对于每一个数,它的数量都是相等的,也就是 \(f[i]=f[i-1]\times 10+10^{(i-1)};\)
( 这里我推荐使用打表+大眼观察法 )

然而这个公式推出来后,你就会面临第二个难题,怎么推出我想要的答案?

我们先设数字为ABCD

A000,如果我们要求出它所有数位之和,我们会怎么求?

鉴于我们其实已经求出了0`9`,`0`99,0~999。。。上所有数字个数( \(f[i]\) , 且没有考虑前导零)我们何不把这个A000看成0000`1000`2000...A000对于不考虑首位每一个式子的数字的出现个数为 \(A\times f[3]\) 。加上首位出现也就是小于 A 每一个数都出现了 \(10^3\) 次,再加上,我们就把 A000 处理完了。

这样你以为就把第一位处理完了?不不不,首位 A 还出现了 \(BCD+1\)次呢,也就是从A000~ABCD,这个A还出现了 \(BCD+1\) 次,所以再加上这些才行呢。那么你发现,我们成功把首位代表的所有数字个数求出来了,剩下的求解与 A 完全没有任何关系,只是 BCD 的求解,于是我们发现我们已经把一个大问题,化成了一个个小问题,也即是,对于一个这样 \(n\) 位的数,把他一位位的分离开来。

当然你还需要处理前导零。你会发现它一定是 0000 , 0001 , 0002 ... 00120013... 0101 , 0102 ... 0999这样的数,一共出现了 \(10\times(i-1)+10\times(i-2)+... 10+i\) (i表示数字位数,最后加 \(i\) 是因为0000也被统计了),让 0 的统计减去这个值,那么恭喜你这道题做完了。

\(\frak{CODE}\)

#include<bits/stdc++.h>  
using namespace std;  
#define N 13  
#define ll long long  
ll teno[N],temu[N];//teno代表小于10^i的所有数的数码出现次数,temu代表10^i  
ll L,R,ans1[11],ans2[11];  
void solve(ll n,ll *ans){  
    int a[N],len=0;  
    while(n>0){  
        a[++len]=n%10;  
        n/=10;  
    }//a就是n的每一位数码,a[len]位最大,a[0]位最小  
    for(int i=len;i>=1;--i){  
        for(int j=0;j<=9;++j)  
            ans[j]+=teno[i-1]*a[i];//1XXX 2XXX 3XXX 4XXXX 5XXX 6XXX 的 XXX 部分数字出现次数  
        for(int j=0;j<a[i];++j)  
            ans[j]+=temu[i-1];//AXXX 的 A 部分数字出现次数  
        ll tmp=0;  
        for(int j=i-1;j>=1;--j)  
            tmp=tmp*10+a[j];    //(a[i])BCD 的 a[i] 在 (a[i])000 到 (a[i])BCD 之间出现了多少个a[i]            
            ans[a[i]]+=tmp+1;    //(a[i])000 还没有统计  
    }  
    for(int i=len-1;i>=1;--i){  
        ans[0]-=(len-i)*temu[i-1]*9;//00AB 这种数字要删掉先导0  
    }                            //10-99都只用删(len-2)位,100-999都只用删(len-3)位,以此类推。  
    ans[0]-=len;                //0000 还没有删除  
    return;  
}  
int main(){  
    temu[0]=1;  
    scanf("%lld %lld",&L,&R);  
    for(int i=1;i<N;++i){  
        teno[i]=teno[i-1]*10+temu[i-1];  
        temu[i]=temu[i-1]*10;  
    }  
    solve(R,ans1);solve(L-1,ans2);  
    for(int j=0;j<=9;++j)  
    printf("%lld ",ans1[j]-j[ans2]);  
    return 0;  
}

标签:10,数字,int,ll,学习心得,len,前导,dp,数位
From: https://www.cnblogs.com/DZhearMins/p/17761990.html

相关文章

  • 割边+割点 学习心得
    先背诵tarjan板子#include<bits/stdc++.h>using namespace std;#define N 10005#define M 100005int tot,first[N],nxt[M],to[M];void add(int x,int y){    nxt[++tot]=first[x];    first[x]=tot;    to[tot]=y;}int n......
  • Almost Sorted (CF F ) (压状dp)
     思路:性质1,相当于重新对这个序列排序性质2, 等式关于值域,对于任意一个都满足,那么就是当前点比前面放入的点的最大值-k都要大,比后面最小值+k都要小,-->每一个点都要满足,那么对于当前点的放置是有限制的,以值域来看1-i里面都已经放置了,那么放置后......
  • 低功耗Sub-1G全频段收发一体芯片DP4306 适用无线对讲机 工业数据采集等应用
    无线电对讲机既是移动通信中的一种专业无线通信工具,又是一种能满足人们生活需要的具有消费类产品特点的消费工具。顾名思义移动通信就是通信一方和另一方在移动中实现通信。它是一种无线的可在移动中使用的一点对多点进行通信的终端设备,可使许多人同时彼此交流,使许多人能同时听到......
  • 云服务测试DPDK
    一、DPDK的系统要求1.1x86上的BIOS的设置先决条件1.1.1 对于大多数平台,不需要特殊的BIOS设置即可使用基本的DPDK功能;1.1.2为了获得额外的HPET定时器和电源管理功能以及小数据包的高性能,可能需要更改BIOS设置;1.2DPDK编译(Ubuntu22.04)......
  • 动态规划——树形DP 学习笔记
    动态规划——树形DP学习笔记引入前置知识:树基础。树形DP,即在树上进行的DP,最常见的状态表示为\(f_{u,\cdots}\),表示以\(u\)为根的子树的某个东东。本文将讲解一些经典题目(树的子树个数、树的最大独立集、树的最小点覆盖、树的最小支配集、树的直径、树的重心、树的中心),以......
  • UOS&windows远程协助:使用xrdp实现远程访问和远程控制
    1.xrdp与vnc的区别在很多场景下,我们需要在局域网内,远程连接到Linux服务器或桌面系统,传统的连接方式主要分为两种。第一种:终端命令行,通过SSH服务实现,没有可视化图形界面,很多人技术牛人喜欢这种方式,因为方便快捷。第二种:图形用户界面,通过xrdp或vnc服务实现,提供可视化图......
  • 换根dp
    看到网上的方法多多少少比较复杂,所以决定写一下。首先对于一道换根dp题应该是先要会不换根版本的。然后可以按照欧拉序(括号序)换根。对于欧拉序中相邻的两个节点必有一条边把它们相连,所以换根的时候只需要从新统计\(1\)个子树的信息。觉得自己的语言表达能力太烂,还是上题目比......
  • 数字预失真(DPD)小试
    前言射频功放的增益响应并非线性的,受到放大管饱和效应的影响,功放不可避免地出现非线性、甚至具有记忆效应的失真。这种非线性失真不仅产生高阶谐波,还会产生互调干扰,降低带内信噪比,影响带外信号。因此,需要一种方式减弱射频功放的非线性增益,数字预失真就是方式之一。ADI有篇文章不......
  • Blazor Server App Cannot find the fallback endpoint specified by route values
    github官方issues中提到的解决方案,CreateBuilder时指定项目绝对路径可以解决。1//指定项目路径,也可以用Assembly.GetCallingAssembly获取2conststringContentRootPath=@"C:\Users\BlazorServer";//项目的路径3conststringApplicationName=nameof(BlazorServer);......
  • 网络基础-OSI七层vsTCP/UDP四层 五层 数据封装
    1.0网络基础1.1网络是什么?网络是信息传输、接收、共享的虚拟平台,通过它把各个点、面、体的信息联系到一起,从而实现这些资源的共享网络分类:局域网,城域网,广域网1.2数据通信方式单播:一对一组播:一对多广播:一对所有2.0OIS七层模型vsTCP/IP四层五层模型 2.1分层思想①......