算法模板——数位dp
来源:互联网 发布:上海1943和老街知乎 编辑:程序博客网 时间:2024/06/03 22:48
数位dp
顾名思义,数位dp就是对每个数位进行dp。一般来说,数位dp的适用范围是求一个区间[a,b]的值,其中a和b会很大,而且值具有可加性。那么对于每个值可以分成一些段,如:2333可以分成求0-999,1000-1999,2000-2299,2300-2329,2330-2333这些段的值。
代码
//[ZJOI2010]count数字计数#include <cstdio>#include <cmath>const int maxn=12;struct data{ long long num[10]; data operator +(const data &other) { data res; for(int i=0; i<=9; i++) { res.num[i]=num[i]+other.num[i]; } return res; }};data f[maxn+1][10];long long t[maxn+1],a,b;int init();data calc(long long n);int main(){ init(); scanf("%lld%lld",&a,&b); data x=calc(a-1),y=calc(b); for(int i=0; i<9; i++) { printf("%lld ",y.num[i]-x.num[i]); } printf("%lld\n",y.num[9]-x.num[9]); return 0;}int init(){ t[1]=1; for(int i=2; i<=13; i++) { t[i]=t[i-1]*10ll; } for(int i=0; i<=9; i++) { f[1][i].num[i]=1; } for(int i=2; i<=12; i++) { for(int j=0; j<=9; j++) { for(int k=0; k<=9; k++) { f[i][k]=f[i][k]+f[i-1][j]; f[i][k].num[k]+=t[i-1]; } } } return 0;}data calc(long long n){ data ans; ans.num[0]=1; for(int i=1; i<=9; i++) { ans.num[i]=0; } if(!n) { return ans; } int len=log(n)/log(10)+1; for(int i=1; i<len; i++) { for(int j=1; j<=9; j++) { ans=ans+f[i][j]; } } int h=n/t[len]; n%=t[len]; for(int i=1; i<h; i++) { ans=ans+f[len][i]; } ans.num[h]+=n+1; for(int i=len-1; i>0; i--) { h=n/t[i]; n%=t[i]; for(int j=0; j<h; j++) { ans=ans+f[i][j]; } ans.num[h]+=n+1; } return ans;}
阅读全文
0 0
- 算法模板——数位dp
- 小白算法练习 数位dp模板
- 数位dp模板
- 数位DP模板
- 数位DP模板
- 数位DP模板
- 【自用模板】数位dp
- 数位DP模板
- 数位DP模板
- 数位DP模板详解
- 数位DP模板
- 数位DP模板
- 数位DP模板
- 数位DP模板
- 数位DP(模板)
- 数位DP模板
- 数位DP模板
- 数位DP模板
- 增1减1运算符使用
- nc常用用法
- 2017秦皇岛
- NOIP模拟 纸带 【线段树】【并查集】
- android MVVM开发框架——(1)DataBinding 基础应用
- 算法模板——数位dp
- QT5之2D绘图-绘制路径
- matlab之自定义方程系数解方程
- Evaluate Reverse Polish Notation--LeetCode
- jdbc的事务管理,连接池的概念
- HDU
- 三周第二次课 2017.10.31 usermod命令、用户密码管理、mkpasswd命令
- Android事件分发机制源码阅读
- Yoshua Bengio——《Deep Learning》学习笔记1