给n<=10^700,问1到n中每个数在各数位排序后得到的数的和。答案膜1e9+7。

一看就是数位DP啦。。然而并没有什么思路。。

可以尝试统计n(i,j)表示数j在第i位的出现次数,知道了这个数组后就可以算答案了。可以枚举j,做一次DP,f(a,b,0/1)--考虑第a~n个数,有b个j,是否大于给定数字(因为当前大于给定数字不一定dp到前面的数就大于,所以当前大于给定数字的数也是有贡献的),等等光知道有多少j并不能确定第i位是否有j,行不通。

套路--k(i,j)表示第i位出现的>=j的数字的出现次数,则$n(i,j)=k(i,j)-k(i,j+1)$。现在f(a,b,0/1)中的b则表示有b个>=j的数,那么就可以递推了。用$X_a$表示给定数字第a位是谁:

1、$j>X_a$:$f(a,b,0)=(f(a+1,b,0)+f(a+1,b,1))*X_a+f(a+1,b,0),f(a,b,1)=(f(a+1,b-1,0)+f(a+1,b-1,1))*(10-j)+(f(a+1,b,0)+f(a+1,b,1))*(j-X_a-1)+f(a+1,b,1)$

2、$j<=X_a$:$f(a,b,0)=(f(a+1,b,0)+f(a+1,b,1))*j+(f(a+1,b-1,0)+f(a+1,b-1,1))*(X_a-j)+f(a+1,b-1,0),f(a,b,1)=(f(a+1,b-1,0)+f(a+1,b-1,1))*(10-X_a-1)+f(a+1,b-1,1)$。

还没完,边界条件:1、$j>X_n$:$f(n,0,0)=X_a+1,f(n,0,1)=j-X_a-1,f(n,1,1)=10-j,f(n,1,0)=0$。

2、$j<=X_n$:$f(n,0,0)=j,f(n,0,1)=0,f(n,1,0)=X_n-j+1,f(n,1,1)=10-X_n-1$。

这些加一减一、取等取不等的特别注意。把<和=归在一类是之前在草稿纸上推过发现可以合的。

然后就没了。注意检查膜。

 //#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<map>
//#include<bitset>
#include<algorithm>
//#include<cmath>
using namespace std; int n;
#define maxn 711
char s[maxn];
const int mod=1e9+;
int kk[maxn][],f[maxn][maxn][];
int main()
{
scanf("%s",s+); n=strlen(s+);
for (int j=;j<=;j++)
{
int num=s[n]-'';
if (j>num) {f[n][][]=num+; f[n][][]=; f[n][][]=j-num-; f[n][][]=-j;}
else {f[n][][]=j; f[n][][]=num-j+; f[n][][]=; f[n][][]=-num-;} for (int a=n-;a;a--)
{
int num=s[a]-'';
if (j>num)
{
f[a][][]=(1ll*(f[a+][][]+f[a+][][])*num+f[a+][][])%mod;
f[a][][]=(1ll*(f[a+][][]+f[a+][][])*(j-num-)+f[a+][][])%mod;
for (int b=,to=n-a+;b<=to;b++)
{
f[a][b][]=(1ll*(f[a+][b][]+f[a+][b][])*num+f[a+][b][])%mod;
f[a][b][]=(1ll*(f[a+][b-][]+f[a+][b-][])*(-j)
+1ll*(f[a+][b][]+f[a+][b][])*(j-num-)+f[a+][b][])%mod;
}
}
else
{
f[a][][]=(1ll*(f[a+][][]+f[a+][][])*j)%mod;
f[a][][]=;
for (int b=,to=n-a+;b<=to;b++)
{
f[a][b][]=(1ll*(f[a+][b][]+f[a+][b][])*j
+1ll*(f[a+][b-][]+f[a+][b-][])*(num-j)+f[a+][b-][])%mod;
f[a][b][]=(1ll*(f[a+][b-][]+f[a+][b-][])*(-num-)+f[a+][b-][])%mod;
}
}
}
for (int i=n;i;i--) f[][i][]+=f[][i+][],f[][i][]-=f[][i][]>=mod?mod:,kk[i][j]=f[][i][];
}
int ans=;
for (int i=,ten=;i<=n;i++)
{
for (int j=;j<=;j++)
ans+=1ll*(kk[i][j]-kk[i][j+]+mod)*ten%mod*j%mod,
ans-=ans>=mod?mod:,ans+=ans<?mod:;
ten=1ll*ten*%mod;
}
printf("%d\n",ans);
return ;
}

Codeforces908G. New Year and 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. 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 ...

  4. 【CF908G】New Year and Original Order

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

  5. CF908G Original Order

    题目大意: 定义\(R(x) = 每个数在各数位排序后得到的数\) 例如:\(R(321597) = 123579\) 给定一个\(n<=10^{700}\),求\(\sum _{i=1}^n ...

  6. CF908G New Year and Original Order 数位DP

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

  7. CF908G New Year and Original Order

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

  8. 908G New Year and Original Order

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

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

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

随机推荐

  1. Kali linux 2016.2(Rolling) 的详细安装(图文教程)附安装VMare Tools 增强工具

    写在前面的话 因读研期间,实验室团队需要,所以,接触上了Kali Linux,需去获得网络安全方面的数据,即数据和信息收集.以便为后续的数据处理和分析,准备! 用到hadoop和spark.机器学习等 ...

  2. Anaconda(miniconda)安装及使用--转

    https://www.waitalone.cn/anaconda-install-error.html         3,224   1.Anaconda概述 Anaconda是一个用于科学计算的 ...

  3. webapp开发学习---Cordova环境搭建

    Cordova 使用HTML, CSS & JS进行移动App开发;多平台共用一套代码;免费开源 步骤:(来自Cordova官网) 1.安装Cordova(在node.js环境下进行安装) 命 ...

  4. IIS 的最大并发数

    为了探寻IIS的最大并发数,先要做几个假设. 1.假设最大并发数就是当前的连接数.意思是当前能承受最大的连接,那么就表明最大的并发.2.假设IIS应用程序池处于默认状态,更改设置将会对最大连接数产生影 ...

  5. jQuery Ajax使用实例

    <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.js"></script> <scr ...

  6. 设计模式 -- Abstract Factory 抽象工厂

    1.常规的对象创建方法 //创建一个Road对象 Road road=new Road(); new的问题:实现依赖,不能应对“具体实例化类型”额变化. 解决思想: 封装变化点--哪里变化,封装哪里( ...

  7. jquery 实现 点击把数据移动右侧 点击再次移回到左侧

    2018年第一发  希望新的一年和大家一下学习更多知识    JS://把数据左边挪到了右边,再从右边移动回来function moveOption(e1, e2){   $("#" ...

  8. java 生成特定范围内的随机数

    /** * 生成[1, max]之间的随机数 */ public static Integer getRandomNumber(Integer max) { Random rd = new Rando ...

  9. 短视频SDK简单易用——来自RDSDK.COM

    锐动天地为开发者提供短视频编辑.视频直播.特效.录屏.编解码.视频转换,等多种解决方案,涵盖PC.iOS.Android多平台.以市场为导向,不断打磨并创新技术,在稳定性,兼容性,硬件设备效率优化上千 ...

  10. div根据鼠标的移入移除显示隐藏

    onmouseout  是把div当成一个对象,div里面包含的元素当成别的对象,所以移动的时候,会隐藏,达不到我们预期的效果. onmouseleave 就是把整个div当成一个对象. 大家可以去试 ...