CF908G Original Order
题目大意:
定义\(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的更多相关文章
- 【CF908G】New Year and Original Order(动态规划)
[CF908G]New Year and Original Order(动态规划) 题面 洛谷 CF 题解 设\(f[i][j][k][0/1]\)表示当前填到了第\(i\)位,有\(j\)个大于等于 ...
- 【CF908G】New Year and Original Order 数位DP
[CF908G]New Year and Original Order 题意:令S(i)表示将i中所有数位上的数拿出来,从小到大排序后组成一个新的数的值.如S(50394)=3459.求$\sum\l ...
- 【CF908G】New Year and Original Order
[CF908G]New Year and Original Order 题面 洛谷 题解 设\(f[i][j][k][l]\)表示当前在第\(i\)位有\(j\)位大于等于\(k\),当前有没有卡上界 ...
- 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 ...
- CF908G New Year and Original Order 数位DP
传送门 看到数据范围到\(10^{700}\)毫无疑问数位DP.那么我们最重要的问题是如何有效地维护所有数位排序之后的数的值. 对于某一个数\(x\),设\(f_{x,i} (i \in [1,9]) ...
- CF908G New Year and Original Order
题面 题意翻译 给定$n<=10^{700}$,问$1$到$n$中每个数在各数位排序后得到的数的和.答案$mod\;10^9+7$. 题解 考虑设$f[i][j][k][0/1]$表示前$i$位 ...
- CF908G New Year and Original Order(DP,数位 DP)
又一次降智…… (数位 DP 原来可以写这么短,学到了) 问题可以转化为求数位中 $\ge k$ 的有恰好 $j$ 位的数的个数.设为 $c_{j,k}$. 那么答案就是:(考虑把 $k$ 的贡献拆开 ...
- 908G New Year and Original Order
传送门 分析 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string ...
- Codeforces908G. New Year and Original Order
给n<=10^700,问1到n中每个数在各数位排序后得到的数的和.答案膜1e9+7. 一看就是数位DP啦..然而并没有什么思路.. 可以尝试统计n(i,j)表示数j在第i位的出现次数,知道了这个 ...
随机推荐
- Node.js爬取豆瓣数据
一直自以为自己vue还可以,一直自以为webpack还可以,今天在慕课逛node的时候,才发现,自己还差的很远.众所周知,vue-cli基于webpack,而webpack基于node,对node不了 ...
- 04-PHP-redis
[Redis] 先安装tcl: yum install tcl [下载和安装] 官网http://redis.io/ 下载最新的稳定版本,这里是3.2.0, 然后解压文件并进入. $ sudo ...
- css绘制倒三角
<style> i{ border-left: 5px solid transparent; border-right: 5px solid transparent; border-top ...
- [记]Debian alias 设置, 不设置貌似有点不方便习惯
备忘录,记录下. 不知道 当前有那些 alias 的话 直接输入 alias ,回车就可以看到 alias 列表. 终端输入: vim ~/bash_aliases 然后输入: # some more ...
- Android 文件下载三种基本方式
一.自己封装URLConnection 连接请求类 public void downloadFile1() { try{ //下载路径,如果路径无效了,可换成你的下载路径 String url = & ...
- Android -传统蓝牙通信聊天
概述 Android 传统蓝牙的使用,包括开关蓝牙.搜索设备.蓝牙连接.通信等. 详细 代码下载:http://www.demodashi.com/demo/10676.html 原文地址: Andr ...
- 1.11 str 字符串
字符串属于不可变序列,是 文本序列. 字符串的声明 >>> #字符串的声明既可以用单引号也可以用双引号,这两个能方法在效果上是一样的 >>> s = '' > ...
- [Essay] Apache Flink:十分可靠,一分不差
Apache Flink:十分可靠,一分不差 Apache Flink 的提出背景 我们先从较高的抽象层次上总结当前数据处理方面主要遇到的数据集类型(types of datasets)以及在处理数据 ...
- Http协议规范及格式
HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616.HTTP协议采用了请求/响应模型.客户 ...
- 前端日常常用git命令
讲真,很早之前就想总结一下git常用的命令了,每次用着用着很多命令都记不住.而且我是英语渣包,有些单词慢慢靠背. git只是一个工具,我这写的只是适合我这种快速上手使用工具的小白,深究的请移步别处. ...