题目

看起来就像是数位\(\rm dp\)

不妨从竖式乘法的角度来考虑这个问题

为了方便处理进位,我们得从低位向高位填数

设\(dp[i][0/1][j][p][t]\)表示填到了第\(i\)位,卡不卡上界,\(f(x)=j\),\(f(k\times x)=p\)(不计算最高位),需要向最高位进\(t\)的\(x\)有多少个

这里的卡上界比较奇怪,如果这一位上填的数大于\(R\)这一位上的数,那么就一定卡了上界,如果小于这一位上的数,那么就一定不卡上界,如果和原来的数相等,那么就继续之前的状态

所以这个\(0/1\)就表示后面的\(i\)为和\(R\)后\(i\)位的大小关系,如果填的数大于\(R\)后\(i\)为,那么这个状态就是\(1\);否则就是\(0\)

至于转移,就比较简单,我们枚举这一位上填什么数\(y\),那么对于\(x\),数位和增加了\(y\),对于\(k\times x\),这一位上直接来一个乘法是\(k\times y\),还有之前的进位\(t\),于是就是\((k\times y+t)\% 10\),新的进位就是\((k\times y+t)/10\)

但是这样我们填到\(R\)的最高位之后可能还有一些进位没有处理,于是再往前多处理\(3\)位把进位处理完

最后的答案就是\(\sum_{i}dp[\lg_{R}][0][i][i][0]\),即\(x\)的数位和等于\(f(k\times x)\)的情况,但是这样多了一维非常难受,考虑的最后只要求\(j=p\),所以我们直接把\(j-p\)看成一维状态就好了

代码

#include<bits/stdc++.h>
#define re register
#define LL long long
LL dp[25][2][1000][500];
int m,w,a[25],M=250;LL n;
inline void split(LL x) {
while(x) a[++w]=(x%10),x/=10;
}
int main() {
scanf("%lld%d",&n,&m);
dp[0][0][0][M]=1;
split(n);
for(re int i=0;i<w+3;i++)
for(re int j=0;j<2;++j)
for(re int k=0;k<1000;++k)
for(re int p=M-2*i*9;p<=M+2*i*9;++p) {
if(!dp[i][j][k][p]) continue;
for(re int t=0;t<10;++t)
dp[i+1][t==a[i+1]?j:t>a[i+1]][(k+t*m)/10][p+t-(k+t*m)%10]+=dp[i][j][k][p];
}
printf("%lld\n",dp[w+3][0][0][M]-1);
return 0;
}

最新文章

  1. SpringMVC基础——一个简单的例子
  2. iOS-集成阿里百川IMSDK的服务端及客户端
  3. [mondrian] 快速入门
  4. Objective-C语言的一些基础特性
  5. Docker 初步认识
  6. Direcshow中视频捕捉和参数设置报告
  7. Redis+Jedis封装工具类
  8. Java注释规范整理
  9. javascript实现div的显示和隐藏
  10. Logback配置解析
  11. javascript浅拷贝和深拷贝
  12. es6 中的generator函数控制流程
  13. 转自IBM:Apache HTTP Server 与 Tomcat 的三种连接方式介绍
  14. JVisualVM简介与内存泄漏实战分析
  15. java基础04 Scanner的使用
  16. centos7关闭图形界面启动系统
  17. URAL - 1627:Join (生成树计数)
  18. 浅谈EntityFramework框架的使用
  19. Windows 服务快捷启动命令,可以直接在运行处运行电脑的功能。
  20. .NET重构(九):机房重构验收总结

热门文章

  1. legend2---开发日志16
  2. flask json
  3. 12、jquery的tree组件
  4. delphi基础篇之数据类型
  5. Django框架(五)—— 虚拟环境搭建
  6. tomcat服务器和HTTP协议
  7. Redis数据结构之字符串-SDS
  8. .Net中Task使用来提高代码执行效率
  9. Ubuntu 常用软件记录【持续更新】
  10. activeMQ的回顾