题目大意:

定义\(R(x) = 每个数在各数位排序后得到的数\)
例如:\(R(321597) = 123579\)
给定一个\(n<=10^{700}\),求\(\sum _{i=1}^n R(i)\)。答案模上\(10^9+7\)。

思路与解法:

难度比较大的一题。显然是要数位\(DP\)的。
最直白的想法就是:求出\(g[i][j]\)表示数字在\(R(x)\)的第\(j\)位出现的次数。
有了这个我们就可以计算答案了。 但是这个玩意不好\(DP\)处理。
考虑数字\(num\)在\(f(x)\)的第\(j\)位出现的条件:\(R(x)\)中大于等于\(num\)的数字有\(j\)个。
这个东西就可以\(DP\)了:
\(f[i][j][k][0/1]\)表示当前确定了\(i\)位数字,
数位中大于等于\(k\)的数位有\(j\)个,数位限制状态为\(0/1\)的数的个数。
转移比较简单,枚举下一位放什么即可。
然后初值不好处理,所以手玩\(i=1\)的,把\(i=1\)当初值就行了。
处理出了\(f[n][j][num][1]\)后,就比较好算答案了。
.
记录后缀和\(ans[num][j] = \sum_{i=j}^n f[n][i][num][1]\)。
那么\(g[i][j] = ans[num][j] - ans[num+1][j]\),就把\(g[i][j]\)求出来了。
然后用\(g[i][j]\)直接计算答案即可。

实现代码:

注:屏幕较窄的电脑上看 代码可能格式不太好,最好拷贝到编辑器后再看。

#include<bits/stdc++.h>
#define RG register
#define IL inline
#define ll long long
#define _ 705
#define mod 1000000007
using namespace std;

ll Ans,ten; int n , num[ _ ];
ll f[ _ ][ _ ][ 10 ][ 2 ],ans[ _ ][ _ ]; char ch[ _ ];

IL void Add(RG ll &x,RG ll y){ x += y; if(x>=mod)x-=mod; }

int main(){
    scanf("%s",ch); n = strlen( ch );
    for(RG int i = 1; i <= n;i ++)
        num[i] = ch[ n-i ] - '0';
    for(RG int t = 0; t <= 9; t ++){
        if(t > num[1])
            f[1][0][t][0] = t , f[1][0][t][1] = num[1]+1 , f[1][1][t][0] = 10-t , f[1][1][t][1] = 0;
        else
            f[1][0][t][0] = t , f[1][0][t][1] = t , f[1][1][t][0] = 10-t , f[1][1][t][1] = num[1]-t+1;
    }
    for(RG int i = 2; i <= n; i ++){
        for(RG int j = 0; j <= i; j ++)
            for(RG int k = 0; k <= 9; k ++){
                for(RG int t = 0; t <= 9; t ++){
                    if(t >= k){
                        Add( f[i][j][k][0] , f[i-1][j-1][k][0] );
                        if( t < num[i] )
                            Add( f[i][j][k][1] , f[i-1][j-1][k][0] );
                        else if( t == num[i] )
                            Add( f[i][j][k][1] , f[i-1][j-1][k][1] );
                    }
                    else if(t < k){
                        Add( f[i][j][k][0] , f[i-1][j][k][0] );
                        if( t < num[i] )
                            Add( f[i][j][k][1] , f[i-1][j][k][0] );
                        else if( t == num[i] )
                            Add( f[i][j][k][1] , f[i-1][j][k][1] );
                    }
                }
            }
        }
    for(RG int nm = 0; nm <= 9; nm ++)
        for (int i = n ; i >= 1 ; i --)
            (f[n][i][nm][1] += f[n][i+1][nm][1]) %= mod , ans[nm][i]=f[n][i][nm][1];
    Ans = 0; ten = 1;
    for(RG int i = 1; i <= n; ten*=10,ten %= mod,i ++)
        for(RG int nm = 1; nm <= 9; nm ++)
            Add( Ans , ( ((ans[nm][i] - ans[nm+1][i]) % mod + mod) % mod * ten % mod * nm % mod) );
    cout << Ans;  return 0;
}

CF908G Original Order的更多相关文章

  1. 【CF908G】New Year and Original Order(动态规划)

    [CF908G]New Year and Original Order(动态规划) 题面 洛谷 CF 题解 设\(f[i][j][k][0/1]\)表示当前填到了第\(i\)位,有\(j\)个大于等于 ...

  2. 【CF908G】New Year and Original Order 数位DP

    [CF908G]New Year and Original Order 题意:令S(i)表示将i中所有数位上的数拿出来,从小到大排序后组成一个新的数的值.如S(50394)=3459.求$\sum\l ...

  3. 【CF908G】New Year and Original Order

    [CF908G]New Year and Original Order 题面 洛谷 题解 设\(f[i][j][k][l]\)表示当前在第\(i\)位有\(j\)位大于等于\(k\),当前有没有卡上界 ...

  4. Good Bye 2017 G. New Year and Original Order

    G. New Year and Original Order time limit per test 2 seconds memory limit per test 256 megabytes inp ...

  5. CF908G New Year and Original Order 数位DP

    传送门 看到数据范围到\(10^{700}\)毫无疑问数位DP.那么我们最重要的问题是如何有效地维护所有数位排序之后的数的值. 对于某一个数\(x\),设\(f_{x,i} (i \in [1,9]) ...

  6. CF908G New Year and Original Order

    题面 题意翻译 给定$n<=10^{700}$,问$1$到$n$中每个数在各数位排序后得到的数的和.答案$mod\;10^9+7$. 题解 考虑设$f[i][j][k][0/1]$表示前$i$位 ...

  7. CF908G New Year and Original Order(DP,数位 DP)

    又一次降智…… (数位 DP 原来可以写这么短,学到了) 问题可以转化为求数位中 $\ge k$ 的有恰好 $j$ 位的数的个数.设为 $c_{j,k}$. 那么答案就是:(考虑把 $k$ 的贡献拆开 ...

  8. 908G New Year and Original Order

    传送门 分析 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string ...

  9. Codeforces908G. New Year and Original Order

    给n<=10^700,问1到n中每个数在各数位排序后得到的数的和.答案膜1e9+7. 一看就是数位DP啦..然而并没有什么思路.. 可以尝试统计n(i,j)表示数j在第i位的出现次数,知道了这个 ...

随机推荐

  1. 读书共享 Primer Plus C-part 12

    第十四章 结构和其他数据形式 1.关于上struct与union 的区别 #include<stdio.h> typedef union Book_u { int pags; int mo ...

  2. 分布式服务dubbo使用

    SOA 服务框架dubbo 节点角色说明: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. Monitor: ...

  3. CentOS 7 安装 Nginx 反向代理 node

    安装 nginx yum install epel-release yum install nginx 配置 nginx sudo vim /etc/nginx/nginx.conf, 改成下面配置: ...

  4. LaTeX 各种命令,符号

    函数.符号及特殊字符 声调 语法 效果 语法 效果 语法 效果 \bar{x} \acute{\eta} \check{\alpha} \grave{\eta} \breve{a} \ddot{y} ...

  5. 传统IO与NIO(channel-to-channel)文件拷贝的探索与性能比对

    Channel-to-channel传输是可以极其快速的,特别是在底层操作系统提供本地支持的时候.某些操作系统可以不必通过用户空间传递数据而进行直接的数据传输.对于大量的数据传输,这会是一个巨大的帮助 ...

  6. POJ - 3126 bfs + 素数筛法 [kuangbin带你飞]专题一

    题意:给定两个四位素数作为终点和起点,每次可以改变起点数的某一位,且改变后的数仍然是素数,问是否可能变换成终点数字? 思路:bfs搜索,每次改变四位数中的某一位.素数打表方便判断新生成的数是否是素数. ...

  7. [Code] 递归函数在函数式 Java 中的实现

    这里以阶乘函数为例,对于阶乘函数 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n - 1) 在函数式 Java 中可以使用 ...

  8. Luogu P2888 [USACO07NOV]牛栏Cow Hurdles

    题目描述 Farmer John wants the cows to prepare for the county jumping competition, so Bessie and the gan ...

  9. HDMI中的AVmute是什么功能

    1. HDMI AVMute是HDMI TMDS数据岛周期General Control Packet中的一个标示. 2. AVMute字面意思是Audio Video Mute声音图像消隐,简单来说 ...

  10. 关于echarts

    昨天随手玩了下echarts,看见同事纠结于echarts的兼容问题. 最简单的echarts(官网的): <div id="main" style="width: ...