Bzoj1833:[ZJOI2010]count 数字计数:数位dp
2016-04-19 16:17
465 查看
题目链接[ZJOI2010]count 数字计数
设f[i][j][k]表示长度为i,开头为j的数中k的个数
分开统计答案,对于位数小于当前数的直接全部加上,剩余的拆分统计
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=51;
LL a,b,ret[maxn],f[maxn][maxn][maxn],bin[maxn];
int d[maxn];
LL solve(LL x,int flag){
int dnum=0; LL tmpn=x;
memset(d,0,sizeof(d));
while(x){d[++dnum]=x%10;x/=10;}
for (int i=1;i<=dnum-1;++i)
for (int j=1;j<=9;++j)
for (int k=0;k<=9;++k)
ret[k]+=(f[i][j][k]*flag);
int tmp=dnum;
while (tmp){
for (int i=0;i<d[tmp];++i){
if (!i&&tmp==dnum) continue;
for (int j=0;j<=9;++j)
ret[j]+=(f[tmp][i][j]*flag);
}
ret[d[tmp]]+=(tmpn%bin[tmp]+1)*flag;
tmp--;
}
}
int main(){
bin[1]=1;
for (int i=2;i<=13;++i) bin[i]=bin[i-1]*10;
for (int i=0;i<=9;++i) f[1][i][i]=1;
for (int i=2;i<=13;++i)
for (int j=0;j<=9;++j)
for (int k=0;k<=9;++k){
for (int z=0;z<=9;++z)
f[i][j][z]+=f[i-1][k][z];
f[i][k][k]+=bin[i-1];
}
scanf("%lld%lld",&a,&b);
solve(b,1); solve(a-1,-1);
for (int i=0;i<=8;++i) printf("%lld ",ret[i]);
printf("%lld\n",ret[9]);
}
设f[i][j][k]表示长度为i,开头为j的数中k的个数
分开统计答案,对于位数小于当前数的直接全部加上,剩余的拆分统计
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=51;
LL a,b,ret[maxn],f[maxn][maxn][maxn],bin[maxn];
int d[maxn];
LL solve(LL x,int flag){
int dnum=0; LL tmpn=x;
memset(d,0,sizeof(d));
while(x){d[++dnum]=x%10;x/=10;}
for (int i=1;i<=dnum-1;++i)
for (int j=1;j<=9;++j)
for (int k=0;k<=9;++k)
ret[k]+=(f[i][j][k]*flag);
int tmp=dnum;
while (tmp){
for (int i=0;i<d[tmp];++i){
if (!i&&tmp==dnum) continue;
for (int j=0;j<=9;++j)
ret[j]+=(f[tmp][i][j]*flag);
}
ret[d[tmp]]+=(tmpn%bin[tmp]+1)*flag;
tmp--;
}
}
int main(){
bin[1]=1;
for (int i=2;i<=13;++i) bin[i]=bin[i-1]*10;
for (int i=0;i<=9;++i) f[1][i][i]=1;
for (int i=2;i<=13;++i)
for (int j=0;j<=9;++j)
for (int k=0;k<=9;++k){
for (int z=0;z<=9;++z)
f[i][j][z]+=f[i-1][k][z];
f[i][k][k]+=bin[i-1];
}
scanf("%lld%lld",&a,&b);
solve(b,1); solve(a-1,-1);
for (int i=0;i<=8;++i) printf("%lld ",ret[i]);
printf("%lld\n",ret[9]);
}
相关文章推荐
- WHOIS类的修改版
- BZOJ3275 Number (最小割)
- Begins and tests
- USACO2013 Nov. Gold T3,一道集合DP
- 数学-素数筛及其拓展
- 最大流模板
- 计算几何模板
- 各种树模板(splay,线段树,可持久化线段树...)
- 上下界网络流初探
- 二分图匹配模板
- CCC 2015 总结&回顾
- acdream 1064
- 【数论】组合数求模
- 【计算几何】POJ 2318 & POJ 2398
- ACM/ICPC World Finals 2013 A Self-Assembly
- 北京集训队 2016 Day4 alarm
- [bzoj1003] [ZJOI2006]物流运输trans
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort