zoukankan      html  css  js  c++  java
  • 数位dp

    有这么一道板子

    题目描述

    给定两个正整数 aa 和 bb,求在 [a,b][a,b] 中的所有整数中,每个数码 (digit) 各出现了多少次。

    输入格式

    输入文件中仅包含一行两个整数 aa、bb,含义如上所述。

    输出格式

    输出文件中包含一行 1010 个整数,分别表示 090−9 在 [a,b][a,b] 中出现了多少次。

    可以记忆化搜索,

    如图hzwer的一样,

    裸的数位dp

    大概只有我这种逗比不会做

    递推出f[i][j][k]表示长度为i开头j的所有数字中k的个数

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstring>
     7 #define ll long long 
     8 using namespace std;
     9 inline ll read()
    10 {
    11     ll x=0,f=1;char ch=getchar();
    12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 struct data{ll a[10];};
    17 ll a,b,t[25];
    18 data f[25][10];
    19 data operator+(data a,data b)
    20 {
    21     data t;
    22     for(int k=0;k<=9;k++)
    23         t.a[k]=a.a[k]+b.a[k];
    24     return t;
    25 }
    26 data cal(ll x)
    27 {
    28     data ans;for(int i=0;i<=9;i++)ans.a[i]=0;
    29     if(!x)
    30     {
    31         ans.a[0]=1;
    32         return ans;
    33     }
    34     int len=15;
    35     while(t[len]>x)len--;
    36     for(int i=1;i<len;i++)
    37         for(int j=1;j<=9;j++)
    38             ans=ans+f[i][j];
    39     ans.a[0]++;
    40     int cur=x/t[len];
    41     for(int i=1;i<cur;i++)
    42         ans=ans+f[len][i];
    43     x%=t[len];
    44     ans.a[cur]+=x+1;
    45     for(int i=len-1;i;i--)
    46     {
    47         cur=x/t[i];
    48         for(int j=0;j<cur;j++)
    49             ans=ans+f[i][j];
    50         x%=t[i];
    51         ans.a[cur]+=x+1;
    52     }
    53     return ans;
    54 }
    55 int main()
    56 {
    57     t[1]=1;for(int i=2;i<=15;i++)t[i]=t[i-1]*10;
    58     for(int i=0;i<=9;i++)f[1][i].a[i]=1;
    59     for(int i=2;i<=12;i++)
    60         for(int x=0;x<=9;x++)
    61             for(int y=0;y<=9;y++)
    62             {
    63                 f[i][y]=f[i][y]+f[i-1][x];
    64                 f[i][y].a[y]+=t[i-1];
    65             }
    66     a=read();b=read();
    67     data t1=cal(b),t2=cal(a-1);
    68     for(int i=0;i<=9;i++)
    69     {
    70         printf("%lld",t1.a[i]-t2.a[i]);
    71         if(i!=9)printf(" ");
    72     }
    73     return 0;
    74 }

    我还能搜索

    #include <cstdio>
    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    
    #define ls (t<<1)
    #define rs ((t<<1)|1)
    #define mid ((l+r)>>1)
    
    #define mk make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    ll p[20];
    ll ans[11]={};
    void chushi() {
        p[0]=1;
        for (int i=1;i<18;i++) {
            p[i]=p[i-1]*10;
        }
        //用于取某一位数 
    }
    
    void dfs(ll x,int f) {
        //x为终点 
        if (x==-1) {
            ans[0]++;
            return;
        }
        for (int k=1;k<10;k++) { 
            for (int i=1;i;i++) {
                //取现在位数 
                ll l=x/p[i];
                ll r=x%p[i-1];
                ll now=x%p[i]/p[i-1];
                if (now>k) {
                    ans[k]+=(l+1)*p[i-1]*f;
                }
                else if(now==k) {
                    ans[k]+=(l*p[i-1]+r+1)*f;
                }
                else ans[k]+=l*p[i-1]*f;
                if (p[i]>x) break;
            }
        }
        for (int i=1;i;i++) {
            //单独处理0 
            ll l=x/p[i];
            ll r=x%p[i-1];
            ll now=x%p[i]/p[i-1];
            if (now>0) ans[0]+=l*p[i-1]*f;
            else ans[0]+=((l-1)*p[i-1]+r+1)*f;
            if (p[i]>x) break;
        }
    }
    ll n,m; 
    
    int main() {
        cin>>n>>m;
        chushi();
        dfs(m,1);
        dfs(n-1,-1);
        for (int i=0;i<=9;i++) {
            cout<<ans[i]<<" ";
            if (i==9) cout<<endl;
        }
        return 0;
    }

    还需好好理解理解


  • 相关阅读:
    第十六章 课程总复习
    第四章 数据类型及数据库基本操作
    第二章.图形化管理工具
    第十三章 指导学习:人机猜拳
    洛谷 P4396 (离散化+莫队+树状数组)
    洛谷 P1351 (枚举)
    洛谷P5322 (BJOI 2019) DP
    P3376 网络最大流模板(Dinic + dfs多路增广优化 + 炸点优化 + 当前弧优化)
    洛谷 P2176(最短路)
    HDU 6556 (2018CCPC吉林 B题)
  • 原文地址:https://www.cnblogs.com/codemaker-li/p/9822043.html
Copyright © 2011-2022 走看看