『The Counting Problem 数位dp』
<更新提示>
<第一次更新>
<正文>
The Counting Problem
Description
求 [L,R]内每个数码出现的次数。
Input Format
若干行,一行两个正整数 L 和 R。
最后一行 L=R=0,表示输入结束。
Output Format
若干行,对于每个询问做出回答,每行 10 个整数,依次表示 0 至 9 出现的次数。
输入的最后一行不属于询问,因此不必对此做出回答。
Sample Input
1 10
114 514
233 666
19260421 19260817
19190504 19890605
0 0
Sample Output
1 2 1 1 1 1 1 1 1 1
80 167 180 180 181 95 80 80 80 80
83 83 150 191 194 194 158 83 83 83
476 475 476 80 159 180 577 180 97 476
350124 1059618 450020 450020 450021 450117 450026 450020 440626 1050224
解析
考虑数位\(dp\),设\(f[i][j][k]\)代表长度为\(i\)的数中,最高位为\(j\),数码\(k\)的出现次数和。以长度作为阶段,可以轻松转移:
\]
当然,对于\(j=k\)的情况,还要加上\(10^{i-1}\),作为最高位数码的贡献。
然后考虑对于一个具体的数值\(x\),求出\(1-x\)的答案。
首先我们可以利用预处理的\(dp\)数组快速得到长度小于\(x\)的长度的答案。然后考虑计算长度等于\(x\)的长度的答案。
从高位到低位枚举,如果当且位小于\(x\)的这一位的话,后面的数字可以随便填,直接累加答案即可,反之累加当前位贡献,继续考虑下一位。
\(Code:\)
#include <bits/stdc++.h>
using namespace std;
const int SIZE = 13;
int cnt,num[SIZE];
long long f[SIZE][10][10],ans[10][2];
inline long long quickpow(long long a,long long b)
{
long long res = 1;
for ( ; b ; a = a * a , b>>=1 )
if ( 1 & b ) res = res * a;
return res;
}
inline void Prepdp(void)
{
for (int i=0;i<=9;i++) f[1][i][i] = 1;
for (int i=2;i<=12;i++)
for (int j=0;j<=9;j++)
{
for (int k=0;k<=9;k++)
for (int l=0;l<=9;l++)
f[i][j][l] += f[i-1][k][l];
f[i][j][j] += quickpow( 10 , i-1 );
}
}
inline void solve(long long x,int id)
{
memset( num , 0 , sizeof num );
cnt = 0; long long y = x;
while ( x ) num[++cnt] = x % 10 , x /= 10;
for (int i=0;i<cnt;i++)
for (int j=1;j<=9;j++)
for (int k=0;k<=9;k++)
ans[k][id] += f[i][j][k];
for (int i=cnt;i>=1;i--)
{
for (int j=0;j<num[i];j++)
{
if ( i == cnt && j == 0 ) continue;
for (int k=0;k<=9;k++)
ans[k][id] += f[i][j][k];
}
ans[num[i]][id] += y % quickpow( 10 , i-1 ) + 1;
}
}
int main(void)
{
Prepdp();
long long a,b;
while ( scanf("%lld%lld",&a,&b) && a && b )
{
solve( a-1 , 0 ) , solve( b , 1 );
for (int i=0;i<=9;i++)
printf("%lld%c",ans[i][1]-ans[i][0]," \n"[i==9]);
memset( ans , 0 , sizeof ans );
}
return 0;
}
<后记>
『The Counting Problem 数位dp』的更多相关文章
- UVA - 1640 The Counting Problem (数位dp)
题意:统计l-r中每种数字出现的次数 很明显的数位dp问题,虽然有更简洁的做法但某人已经习惯了数位dp的风格所以还是选择扬长避短吧(说白了就是菜啊) 从高位向低位走,设状态$(u,lim,ze)$表示 ...
- POJ2282:The Counting Problem(数位DP)
Description Given two integers a and b, we write the numbers between a and b, inclusive, in a list. ...
- 『月之谜 数位dp』
月之谜 Description 打败了Lord lsp 之后,由 于lqr 是一个心地善良的女孩 子,她想净化Lord lsp 黑化的 心,使他变回到原来那个天然 呆的lsp--在倒霉的光之英 雄ap ...
- hdu 5106 Bits Problem(数位dp)
题目链接:hdu 5106 Bits Problem 题目大意:给定n和r,要求算出[0,r)之间全部n-onebit数的和. 解题思路:数位dp,一个ct表示个数,dp表示和,然后就剩下普通的数位d ...
- hiho1259 A Math Problem (数位dp)
题目链接:http://hihocoder.com/problemset/problem/1259 题目大意:g(t)=(f(i)%k=t)的f(i)的个数 求所有的(0-k-1)的g(i)的异或总值 ...
- 哈尔滨工程大学ACM预热赛 G题 A hard problem(数位dp)
链接:https://ac.nowcoder.com/acm/contest/554/G Now we have a function f(x): int f ( int x ) { if ( ...
- nowcoder A hard problem /// 数位DP
题目大意: 称一个数x的各个数位之和为f(x) 求区间L R之间 有多少个数x%f(x)==0 #include <bits/stdc++.h> using namespace std; ...
- 『最长等差数列 线性DP』
最长等差数列(51nod 1055) Description N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不 ...
- 『快乐链覆盖 树形dp』
快乐链覆盖 Description 给定一棵 n 个点的树,你需要找至多 k 条互不相交的路径,使得它们的长度之和最大 定义两条路径是相交的:当且仅当存在至少一个点,使得这个点在两条路径中都出现 定义 ...
随机推荐
- Spring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory);方法源码如下: protected void invokeBeanFactoryPostProcessors( ...
- python基础(2):python的安装、第一个python程序
1. 第一个python程序 1.1 python的安装 自己百度,这是自学最基本的,安装一路确定即可,记得path下打钩. 1.2 python的编写 python程序有两种编写方式: 1.进入cm ...
- Java生鲜电商平台-促销架构以及秒杀解决方案实战
Java生鲜电商平台-促销架构以及秒杀解决方案实战 背景:随着这几年的电商的大热,我们经常看到一些商家为了促销和快速收益,纷纷推出了秒杀活动.不管是日常的超市里面的促销,明星演唱会门票售卖,还是春节订 ...
- AQS(抽象队列同步器)
AQS(全称为AbstractQueuedSynchronizer),即抽象队列同步器,它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列. state的访问方 ...
- java报错问题记录
java.lang.NoSuchMethodError 运行时错误,再编译期一般不会出现这个问题.NoSuchMethodError中文意思是没有找到方法,遇到这个错误并不是说依赖的jar包.方法不存 ...
- 如何将HTML页面中的文本设置首行缩进
text-indent属性介绍 属性值单位 描述 em 比如:1em 就代表缩进1个字,2em缩进2个字...... 由于简单我就不过多的介绍了直接上代码了哦,注意:text-indent属性的值支持 ...
- JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?
<JavaScript 深入浅出>系列: JavaScript 深入浅出第 1 课:箭头函数中的 this 究竟是什么鬼? JavaScript 深入浅出第 2 课:函数是一等公民是什么意 ...
- PyCharm常用快捷键(pycharm使用教程)
pycharm常用快捷键与设置 pycharm高频率使用的快捷键 Ctrl+Shift+F10 运行当前的页面 Ctrl + / 注释(取消注释)选择的行 Ctrl+Shift+F 高级查找 Shif ...
- python中Socket的使用
说明 前一段时间学习python网络编程,完成简单的通过python实现网络通信的功能.现在,将python中Socket 通信的基本实现过程做一个记录备份. Socket通信 python 中的so ...
- js的运用
JS数组的4种声明方法: //第一种 ,,,,] console.log(A) //第二种 var B=new Array(); B[]= B[]= B[]= console.log(B)//第三种 ...