【bzoj 1833】【codevs 1359】 [ZJOI2010]count 数字计数(数位dp)
来源:互联网 发布:js数组去重 es6 编辑:程序博客网 时间:2024/05/16 17:22
1833: [ZJOI2010]count 数字计数
Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2774 Solved: 1230
[Submit][Status][Discuss]
Description
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
Input
输入文件中仅包含一行两个整数a、b,含义如上所述。
Output
输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
Sample Input
1 99
Sample Output
9 20 20 20 20 20 20 20 20 20
HINT
30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。
Source
Day1
【题解】【数位dp】
[自己乱搞的结果就是写了三遍。。。每一遍想法都有所改变……蠢哭]
【刚开始想的是用f[i][j][k][o][x][y]表示第i位放j时k的出现次数,o表示前导0,x,y表示是否到达左右边界,每次下一位与当前位的相同时,更新时就加1,然后,怎么搞都错成一团。。。扔掉!】
【然后,又考虑用f[i][j][k][o][x][y]表示第i位放j时j出现的次数k,o表示前导0,x,y表示是否到达左右边界,每一次都是加上更新过来的f[i][j][k][o][x][y],然后,发现怎么搞1都不对。。。又扔掉!】
【最后,结合前两次的经验,先循环一重当前要求数t的出现次数,用f[i][j][k][o][x][y]表示第i位放j时t的出现次数k,o表示前导0,x,y表示是否到达左右边界。循环9次,卡过了。。。】
【注意,这种方法,由于要判断前导0,把零先去掉了,如果区间中包含0的话,要特判】
#include<cstdio>#include<cstring>#include<algorithm>#define ll long longusing namespace std;ll a,b,ans;int al[15],ar[15],left[15],right[15],l,r,len;int f[15][12][15][3][3][3];int main(){freopen("int.txt","r",stdin);freopen("my.txt","w",stdout);int i,j,k,xx;scanf("%lld%lld",&a,&b); xx=a;while(a) left[++l]=a%10,a/=10;while(b) right[++r]=b%10,b/=10;len=max(l,r);memset(f,0,sizeof(f));for(i=1;i<=len;++i) al[len-i+1]=left[i],ar[len-i+1]=right[i];for(int t=0;t<=9;++t) { memset(f,0,sizeof(f));for(i=al[1];i<=ar[1];++i) f[1][i][i==t&&i!=0][i==0][i==al[1]][i==ar[1]]=1; for(i=1;i<len;++i) for(j=0;j<=9;++j) for(k=0;k<=12;++k) for(int o=0;o<=1;++o) for(int x=0;x<=1;++x) for(int y=0;y<=1;++y) if(f[i][j][k][o][x][y]) { if(x&&y) { for(int h=al[i+1];h<=ar[i+1];++h) { int p; if(h||!o) p=k+(t==h),f[i+1][h][p][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; else p=0,f[i+1][h][0][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; } continue; } if(!x&&!y) { for(int h=0;h<=9;++h) { int p; if(h||!o) p=k+(t==h),f[i+1][h][p][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; else p=0,f[i+1][h][p][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; } continue; }if(!x) { for(int h=0;h<=ar[i+1];++h) { int p; if(h||!o) p=k+(t==h),f[i+1][h][p][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; else p=0,f[i+1][h][p][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; } continue; }if(!y) { for(int h=al[i+1];h<=9;++h) { int p; if(h||!o) p=k+(t==h),f[i+1][h][p][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; else p=0,f[i+1][h][p][o&(h==0)][x&(h==al[i+1])][y&(h==ar[i+1])]+=f[i][j][k][o][x][y]; } continue; }}ans=0;for(i=0;i<=9;++i) for(j=1;j<=12;++j) for(k=0;k<=1;++k) ans+=(ll)(f[len][i][j][k][1][1]+f[len][i][j][k][1][0]+f[len][i][j][k][0][1]+f[len][i][j][k][0][0])*j;if(!t&&!xx) printf("%lld ",ans+1); else printf("%lld ",ans);if(t==9) printf("\n"); }return 0;}
0 0
- 【bzoj 1833】【codevs 1359】 [ZJOI2010]count 数字计数(数位dp)
- bzoj 1833: [ZJOI2010]count 数字计数(数位dp)
- BZOJ 1833 ZJOI2010 count 数字计数 数位DP
- BZOJ 1833 [ZJOI2010]count 数字计数(数位dp)
- 【BZOJ 1833】 [ZJOI2010]count 数字计数|数位DP
- [bzoj 1833] [ZJOI2010]count 数字计数:数位DP
- BZOJ-1833 [ZJOI2010]count 数字计数 数位DP
- bzoj 1833 [ZJOI2010]count 数字计数 数位dp
- 1833: [ZJOI2010]count 数字计数 数位dp
- 【BZOJ】【P1833】【ZJOI2010】【count 数字计数】【题解】【数位DP】
- bzoj1833: [ZJOI2010]count 数字计数 数位dp
- [BZOJ1833] [ZJOI2010]count 数字计数 && 数位DP
- 【bzoj1833】[ZJOI2010]count 数字计数 数位DP
- Bzoj1833:[ZJOI2010]count 数字计数:数位dp
- bzoj1833[ZJOI2010]count 数字计数 数位DP
- BZOJ 1833: [ZJOI2010]count 数字计数 数位DP,处理前导0
- [BZOJ1833][ZJOI2010]count 数字计数(数位dp)
- bzoj1833: [ZJOI2010]count 数字计数(数位Dp)
- 打造完美的ImageLoader——LruCache+DiskLruCache
- ShapeFile数据到mongodb的导入
- BIOS警报声
- Java面向对象编程(3)--抽象类,接口,final
- Error: libcudart.so.7.5: cannot open shared object file: No such file or directory
- 【bzoj 1833】【codevs 1359】 [ZJOI2010]count 数字计数(数位dp)
- MongoDB的地埋空间数据存储、空间索引以及空间查询
- HTML+CSS基础 a标签创建一个在当前页面跳转到指定网页的超链接
- python 编码 乱码问题 ascii unicode utf-8
- 怎样设计一个模块A 当这个模块状态发生变化时,使其它模块可以得知?
- Struts的Action接口---(2)Method属性方法调用。
- 23种设计模式
- 二叉查找树
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)