首页 > 其他分享 >关于此题[ABC 387]C - Snake Numbers 数位DP的一些总结

关于此题[ABC 387]C - Snake Numbers 数位DP的一些总结

时间:2025-01-11 11:15:05浏览次数:1  
标签:ABC && lead pos long st Snake 此题 dp

传送门
这道题要求我们求[l,r]范围内所有的“蛇数”,即这个数的第一位严格大于它的其他位的数。
看到数据范围并且发现答案区间可加减性联想到数位DP。其实有点类似模板题,与经典的数位DP题类似的,我们需要判断前导0,需要判断当前枚举的数是否是贴着所给的数,在此题中如果想要记忆化的话,还需要加两个量,即d表示当前枚举的数首位是什么,还有st表示当前枚举的数首位在什么位置,这两个是为了dp数组记忆化服务,若是没有这两个的话dp数组就没办法精确地记录各种情况的答案。
代码:

#include<bits/stdc++.h>

using namespace std;

long long t;
const long long N = 2e5 + 10;
long long l,r;
long long dp[20][20][20][20];
vector<long long> digit;

long long dfs(long long pos,long long statu,long long d,long long lead,long long done,long long st) {
                                            //pos:当前从高到低枚举到的位置,statu:上一个数是多少(其实可要可不要),d:当前枚举的数首位是多少,lead:当前是否是前导0,done:当前枚举的数是否贴着所给的数,st:当前枚举的数第一位是什么
    if(pos == -1) return 1;
    if(!lead && !done && ~dp[pos][statu][st][d] && d) return dp[pos][statu][st][d];
    long long res = 0,end = done ? digit[pos] : 9;
    for(long long i = 0;i <= end;i++) {
        if(d && i >= d) continue;
        bool flag = (lead && !i);
        long long tmp,ss;
        if(lead && flag) tmp = 0,ss = 0;
        else if(lead && !flag) tmp = i,ss = pos;
        else tmp = d,ss = st;
        res += dfs(pos-1,i,tmp,flag,done && i == end,ss);
    }
    if(!done && !lead) dp[pos][statu][st][d] = res;
    return res;
}

long long work(long long k) {
    memset(dp,-1,sizeof dp);
    digit.clear();
    while(k) {
        digit.push_back(k % 10);
        k /= 10;
    }
    return dfs(digit.size()-1,0,0,1,1,0);
}

void solve() {
    cin >> l >> r;
    cout << work(r) - work(l-1);
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    t = 1;
    while(t--) solve();

    return 0;
}

标签:ABC,&&,lead,pos,long,st,Snake,此题,dp
From: https://www.cnblogs.com/lwiwi/p/18665372

相关文章

  • [ABC311D] Grid Ice Floor
    前言:题解看不懂,太高深了(我太蒻了),于是自己写了一篇。思路:bfs大法,记录新的单次滑倒的中点(撞石头),并记录经过的点,总之还是很简单的。代码:#include<bits/stdc++.h>usingnamespacestd;constintN=210;intn,m;intvis[N][N],cnt[N][N];intdx[4]={0,0,-1,1};intdy[4......
  • 关于此题[ABC367E] Permute K times倍增思想的一些总结
    传送门第一次接触到倍增思想是用来求lca时,为了避免一层一层往上爬浪费时间复杂度。再后来就是区间DP中一小类问题或者是部分图上问题可以用倍增来优化。那么这道题其实可以看作图上问题来使用倍增优化。看到这道题的数据范围,K达到了\(10^{18}\)量级,这让我们不得不思考log级别往......
  • 关于此题[ABC367F] Rearrange Query随机化哈希的一些总结
    传送门这道题要求我们对于非常多的询问回答[l,r]、[L,R]这样两个区间内A、B数组中各个数的出现次数是否相同。看到这道题似乎想到了刚开始学编程的时候就想过的一个问题(bushi,那就是我能不能直接用,例如说这段区间和是否相同,或者说这段区间乘积之类的是否相同来判断这个区间各个数......
  • AT_abc248_h [ABC248Ex] Beautiful Subsequences 题解
    题目传送门前置知识树状数组|序列分治解法考虑序列分治,设因\(\max\)和\(\min\)形成的分节点先后为\(k_{1},k_{2}\)。对于\(j\in(mid,k_{1}]\),等价于统计满足\(\max\limits_{h=i}^{mid}\{a_{h}\}-\min\limits_{h=i}^{mid}\{a_{h}\}\lej-i+k\)的\(j\)的......
  • Atcoder ABC329E Stamp 题解 [ 绿 ] [ 线性 dp ]
    Stamp:难点主要在dp转移的细节与分讨上,但通过改变状态设计可以大大简化分讨细节的题。观察首先要有一个观察:只要某一个前缀能被覆盖出来,那么无论它后面多出来多少,后面的字符串都可以帮他重新覆盖回去。这也就是dp为啥没有后效性的原因。除此之外,还要注意一个字符串不仅能在......
  • 【空间光-光耦合技术06】高斯光束、ABCD定律
    本部分的学习参考柯熙政老师的《无限光通信中的空间光——光纤耦合技术》及欧攀老师的《高等光学仿真(MATLAB版)》,为自学笔记,博客末尾附上了在学习过程中参考的博客内容。基本概念         考虑从光纤端面输出光的传播及耦合。对于光纤端面的出射光(辐射光场),研究者感兴......
  • org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException
    1、问题概述将一个springboot项目打成Jar包后,在本地使用java-jar命令启动服务,服务能启动成功,但是会有如下报错信息。说明:配置文件为外置配置文件,与jar处于同目录下启动命令如下:java-jarblade-gateway.jar--spring.config.location=application-dev.yml--serve......
  • AtCoder备赛刷题 ABC 361 | x = a^b
    学习C++从娃娃抓起!记录下AtCoder(日本算法竞技网站)备赛学习过程中的题目,记录每一个瞬间。附上汇总贴:AtCoder备赛刷题|汇总【ProblemStatement】Howmanyintegersxx......
  • AtCoder备赛刷题 ABC 361 | Go Territory
    学习C++从娃娃抓起!记录下AtCoder(日本算法竞技网站)备赛学习过程中的题目,记录每一个瞬间。附上汇总贴:AtCoder备赛刷题|汇总【ProblemStatement】ThereareNNNston......
  • 关于此题CF[Hello 2025] 2057C - Trip to the Olympiad的一些总结
    传送门题目大意:给定两个数l,r,试求l~r中选三个数a,b,c,使得\((axorb)+(bxorc)+(axorc)\)的值最大。有关此类异或最大的题目,首先想到的是确定最高位,因为假如说异或后二进制下k位置为1,那么此时答案就已经比k位置不为1,而k以后的位置都是1的情况要大了。而观察l,r这两个数,我......