首页 > 其他分享 >AT_tdpc_number 数 解题报告

AT_tdpc_number 数 解题报告

时间:2024-08-28 21:39:04浏览次数:10  
标签:le return int pos num number include 解题 tdpc

题目大意

求 \([1, N]\) 中有多少个数在十进制表示下数码和是 \(D\) 的倍数。

数据范围:\(1\le N\le 10^{10000},1\le D\le 100\)。

思路

很明显的数位 dp。

这里采用了记忆化搜索来实现数位 dp。

记忆化搜索实现比较板子,不光写起来比较简单,而且容易扩展,所以建议大家都学习一下。

首先把上界 \(N\) 的每一位抠出来,然后进行填数,个人喜欢从最高位开始填。

加上记忆化,设 \(f(pos, r)\) 表示在没有顶上界和前导零的情况下,当前填到了第 \(pos\) 位,余数为 \(r\) 的数的个数。

然后在搜索过程中记一下当前数位和 \(\bmod p\) 等于多少,再简单转移一下即可,详细注释在代码中。

注意到状态数为 \(D\cdot\lg N\),每次转移时最多枚举 \(10\) 个可填的数,所以时间复杂度为 \(O(D\cdot \lg N)\),可以通过此题。

注意!由于最后要 \(-1\),所以为防止减为负数要先加上模数再取模。

\(\texttt{Code:}\)

#include <cmath>
#include <vector>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 10010, M = 110, mod = 1e9 + 7;
typedef long long ll;
char s[N];
int len, d;
int f[N][M];
vector<int> num;

//记忆化搜索
//pos 记录当前填到了哪一位,r 记录填完 pos + 1 到 len - 1 位后数位和模 d 的值
//limit 记录当前有没有顶上界,zero 记录当前是不是前导零
ll dfs(int pos, int r, bool limit, bool zero) {
    //边界,若填完了就检查一下是否符合条件
    if(pos < 0) return (r == 0);
    //若不顶上界且没有前导零就记忆化,因为顶上界和前导零是特殊情况,满足条件的数可能和普通情况不同
    if(!limit && !zero && f[pos][r] != -1) return f[pos][r];
    //看一下当前这位需不需要顶上界,若前面填的数都是贴着上界的,这一位最多只能填到 num[pos],否则不受限
    int mx = (limit ? num[pos] : 9);
    ll res = 0;
    //枚举第 pos 位填什么
    for(int i = 0; i <= mx; i++)
        //去填下一位,更新当前余数,看下一位是不是顶上界,看下一位是不是前导零
        res = (res + dfs(pos - 1, (r + i) % d, limit && (i == num[pos]), zero && (!i))) % mod;
    //若不顶上界且没有前导零就记忆化
    if(!limit && !zero) f[pos][r] = res;
    return res;
}

ll calc(char str[]) {
    //把每一位抠出来,注意是倒过来的
    for(int i = len - 1; i >= 0; i--)
        num.push_back(s[i] - '0');
    memset(f, -1, sizeof f);
    return dfs(len - 1, 0, 1, 1);
}

int main() {
    scanf("%s%d", s, &d);
    len = strlen(s);
    //因为我们搜索考虑了 0,最后要把一减去
    printf("%lld", (calc(s) + mod - 1) % mod);
    return 0;
}

标签:le,return,int,pos,num,number,include,解题,tdpc
From: https://www.cnblogs.com/Brilliant11001/p/18385569

相关文章

  • 南沙区信奥赛CSP-J/S 陈老师解题:1350:【例4-11】最短网络(agrinet)
    ​ 【题目描述】农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。你将得到一......
  • PMP考前必看!PMP解题思路分享
    俗话说“临阵磨枪,不快也光”,PMP考试前看完这几点,助你顺利上岸~1、相关方之间的冲突在执行相关方分析时,项目经理识别出两个关键干系人之间的负面关系。其中一个正在为项目提供资金,另一个是客户。项目经理应该如何处理?答:在平等基础上对待所有相关方并进行沟通,通过深入沟通......
  • 题解:P10922 Happybob's Numbers (UBC001B)
    主要思路:贪心,构造。思路构造题,首先明确要删的就是小于\(n\)的数,因为若删了大于等于\(n\)的数就无法进行之后的操作了。那这道题就简单了,先从大到小排序,遇到小于当前长度\(k\)的数,就将这个数删掉,这时长度需减\(1\),毕竟顺序可以自己调,将下一个小于当前\(k\)的数,放到下一......
  • 全网最易懂的解题——C语言“打印一个数的每一位(递归)”
    很简单吧递归我们做了很多题,逆序打印数字和逆序打印数组我们也做过代码就直接附上了voidmy_print(intnum){ if(num<10)//说明只有一位数字 { printf("%d",num); } else { my_print(num/10); printf("%d",num%10); }}//打印数字的每一位intmain(......
  • 全网最易懂的解题——C语言“求斐波那契数(递归)”
    那先来知道什么是斐波那契数列吧前两个数相加等于第三个数,如果其中数字都满足此条件,那么这就是斐波那契数列 现在我们要求第n个斐波那契数,代码框架先搭出来吧,找斐波那契数的函数就命名为Fib吧//求斐波那契数intmain(){ intn=0; printf("请输入你想知道第几个斐波......
  • el-input-number设置精度precision=2,输入2自动变成了2.00怎么办?
    问题背景项目:vue2+elementui老板说:有一个需求,这个输入框最多输入4位数,如果有小数的话,最多输入4位小数,能做吗?我说:“能!”然后我就兴冲冲地做了起来。我一想:“这个直接用el-input-number写不就好了吗”然后我设置了:(最大值9999,精度设置为4,即保留4位小数)<el-input-num......
  • [ARC182C] Sum of Number of Divisors of Product 题解
    题目链接点击打开链接题目解法我怎么不会分治/fn首先把\(x\)分解成\(\prodp_i^{x_i}(0\lei\le5)\)的形式,正因数个数为\(\prod(x_i+1)\)有一个很牛的想法是:合并两个\(x_i\)序列(假设一个叫\(x_0,...,x_5\),另一个叫\(y_0,...,y_5\))先不考虑后面的\(+1\)(可以最后......
  • CF2003E解题报告
    题目描述(来自谷歌翻译)Turtle为您提供\(m\)个区间\([l_1,r_1],[l_2,r_2],\ldots,[l_m,r_m]\)。他认为,如果每个区间(\(l_i\lek_i<r_i\))都存在一个整数\(k_i\),则排列\(p\)是有趣的,并且如果他让从\(1\)到\(m\)的每个整数\(i\)都存在\(a_i=\max\limi......
  • CF2003F 解题报告
    题目描述现在有三个长度为\(n\)的序列\(a,b,c\)。你需要提取一个子序列\(p_1,p_2,\dots,p_m\),满足如下条件:\(\foralli\in(1,m],p_i>p_{i-1}\)。\(\foralli\in(1,m],a_i\geqa_{i-1}\)。\(b_{p_1},b_{p_2},\dots,b_{p_m}\)是互不相同的。在此基础上最大化......
  • [Javascript + Performance] How to run a large number of time-consuming tasks and
    Tryoption1:Promise PromiserunninginMicrotaskqueue,andrenderingshouldwaituntilthequeueisempty;Ifyouhavealargenumberoftime-consuminginmicrotask,itwillalsoblockrenderingfunctionrunTask(task){Promise.resolve().then(()=&g......