• CF908G New Year and Original Order 数位DP


    数位 DP.  

    题意:给定 $n leqslant 10^{700}$,求 $1$ 到 $n$ 中每个数在各数位排序后得到的数的和.       

    这道题从整体上看上去貌似不太可做,不妨从每一位开始考虑.    

    比如说我们可以考虑第 $i$ 位为 $k$ 的数目,然后乘上 $10^i$ 后就是这一位的贡献了.       

    这么做的好处是不用考虑其他位置上填的是什么.    

    直接求第 $i$ 个位置上是 $k$ 不太好求,不妨考虑大于等于 $k$ 的方案数.     

    那么 $k$ 的贡献就是 $sum f[i][j]$ 其中 $j leqslant k$.   

    由于 $j$ 在 $1$ ~ $k$ 时会贡献 $k$ 次,所以我们求出 $f[i][j]$ 乘上对应次幂加和就是答案了.    

    假如第 $i$ 位置的数大于等于 $k$,那么 $i+1$ ~ $n$ 位置的数也必须大于等于 $k$.  

    所以不妨设状态 $f[i][j][k][l]$ 表示当前考虑到第 $i$ 位,有 $j$ 个位置大于等于 $k$,是否顶着 $n$ 的上界.      

    这个可以用数位 DP 求,转移也比较简单.   

    然后考虑最后求出了 $f[n][j][k][0/1]$,第 $i$ 位置的贡献就是 $sum f[n][j][k][0/1] imes 10^j$ ( $i leqslant j$)    

    那么总结下来就是 $ans=sum f[n][j][k][0/1] imes 111111$ ( $j$ 个 1)                

    code:  

    #include <cstdio> 
    #include <cstring>
    #include <algorithm>    
    #define N 703   
    #define ll long long 
    #define mod 1000000007
    #define setIO(s) freopen(s".in","r",stdin)   
    using namespace std; 
    char str[N];    
    int n,a[N],f[N][N][10][2];    
    int main() {
        // setIO("input");     
        scanf("%s",str+1),n=strlen(str+1);   
        for(int i=1;i<=n;++i) a[i]=str[i]-'0';      
        for(int i=1;i<=9;++i) f[0][0][i][0]=1;       
        for(int i=0;i<n;++i) {          
            for(int k=1;k<=9;++k) {     
                for(int j=0;j<=i;++j) {             
                    for(int l=0;l<2;++l) { 
                        int lim=l?9:a[i+1];      
                        for(int p=0;p<=lim;++p) {
                            (f[i+1][j+(p>=k)][k][l|(p<a[i+1])]+=f[i][j][k][l])%=mod;    
                        }
                    }
                }
            }
        }          
        int ans=0; 
        for(int k=1;k<=9;++k) {         
            int re=1;    
            for(int i=1;i<=n;++i) {  
                (ans+=(ll)re*(f[n][i][k][0]+f[n][i][k][1])%mod)%=mod;   
                re=(ll)((ll)re*10%mod+1)%mod;    
            }
        }
        printf("%d
    ",ans);     
        return 0;  
    }
    

      

  • 相关阅读:
    C#学习-多态
    C#学习-子类的初始化顺序
    C#学习-面向对象
    Python数据类型知识点全解
    python 复制图片到剪贴板
    pyperclip
    pyautogui
    多线程代码案例
    常用正则表达式最强整理(速查手册)
    python os
  • 原文地址:https://www.cnblogs.com/guangheli/p/13292904.html
Copyright © 2020-2023  润新知