zoukankan      html  css  js  c++  java
  • [BZOJ1833][ZJOI2010]Count数字计数(DP)

    数位DP学傻了,怎么写最后都写不下去了。

    这题严格上来说应该不属于数位DP?只是普通DP加上一些统计上的判断吧。

    首先复杂度只与数的位数$omega$有关,所以怎么挥霍都不会超。

    f[i][j][k]表示所有i位数(可以有前导零),第一位数为j,数字k出现的次数。直接$O(omega^4)$转移即可。

    接下来只需要统计[1,n]中某个数字出现的次数,分两种情况。

    1. 第一位是0:这个直接做就好了。

    2. 第一位不是0:枚举第一个小于原数的位置,同样直接转移。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=15;
     9 ll a,b,d[N],bin[N],f[N][N][N],res[N];
    10 
    11 void solve(ll x,int flag){
    12     int len=0; ll tt=x;
    13     memset(d,0,sizeof(d));
    14     while (x) d[++len]=x%10,x/=10;
    15     rep(i,1,len-1) rep(j,1,9) rep(k,0,9) res[k]+=f[i][j][k]*flag;
    16     for (int tmp=len; tmp; tmp--){
    17         rep(i,(tmp==len),d[tmp]-1)
    18             rep(j,0,9) res[j]+=f[tmp][i][j]*flag;
    19         res[d[tmp]]+=(tt%bin[tmp]+1)*flag;
    20     }
    21 }
    22 
    23 int main(){
    24     freopen("bzoj1833.in","r",stdin);
    25     freopen("bzoj1833.out","w",stdout);
    26     scanf("%lld%lld",&a,&b);
    27     bin[1]=1;
    28     rep(i,2,13) bin[i]=bin[i-1]*10;
    29     rep(i,0,9) f[1][i][i]=1;
    30     rep(i,2,13) rep(j,0,9) rep(k,0,9){
    31         rep(p,0,9) f[i][j][p]+=f[i-1][k][p];
    32         f[i][k][k]+=bin[i-1];
    33     }
    34     solve(b,1); solve(a-1,-1);
    35     rep(i,0,9) printf("%lld ",res[i]);
    36     return 0;
    37 }
  • 相关阅读:
    Linux
    python 鸢尾花数据集报表展示
    python 词云
    毕业设计回顾
    editor.md
    杂记
    垃圾回收器
    杂记
    随笔
    杂记
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9279210.html
Copyright © 2011-2022 走看看