【CF886E】Maximum Element DP
【CF886E】Maximum Element
题意:小P有一个1-n的序列,他想找到整个序列中最大值的出现位置,但是他觉得O(n)扫一遍太慢了,所以它采用了如下方法:
1.逐个遍历每个元素,如果这个元素比当前记录的最大值大,则令最大值等于当前元素,并令cnt=0
2.如果这个元素没有当前元素大,则cnt++。
3.如果cnt=k,则返回当前最大值
现在小P想知道有多少种序列在使用他的方法时会得到错误的答案。为了简化问题,我们假定原序列是一个1-n的排列。即我们要求的是:给定n和k,有多少个1-n的排列,在使用上述算法时,会得到错误的答案。
n,k<=10^6
题解:好难的DP题。
令f[n]表示1-n的排列中,$a_n=n$且能得到错误答案的方案数。显然当n<=K时f[n]都是0。
考虑枚举n-1的出现位置,如果n-1的出现位置在[1,n-k-1]中,那么这样的排列一定是错误的。这样的方案数是(n-2)!*(n-k-1)。
如果n-1在[n-k,n-1]中,那么如果答案是错误的,最大值只能是前n-2个数中的一个。设n-1的位置是j,那么我们将n-1和它前面的数看成一个新的序列,那么这个序列错误的方案数就是f[j]。又由于前面的j个数其实可以在n-2里随便取,所以方案数其实是$f[j]\frac {(n-2)!} {(j-1)!}$。
所以DP方程:$f[n]=(n-2)!(n-k-1)+\sum\limits_{j=n-k}^{n-1}f[j]\frac{(n-2)!}{(j-1)!}$
用前缀和维护$\frac{f[j]}{(j-1)!}$即可。
答案是什么呢?仿照上面的推导过程可以知道$ans=\sum\limits_{i=k+1}^nf[i]\frac{(n-1)!}{(i-1)!}$。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=1000010;
const ll P=1000000007;
int n,m;
ll jc[maxn],ine[maxn],jcc[maxn],f[maxn],s[maxn];
int main()
{
scanf("%d%d",&n,&m);
int i;
ine[0]=ine[1]=jc[0]=jc[1]=jcc[0]=jcc[1]=1;
for(i=2;i<=n;i++) jc[i]=jc[i-1]*i%P,ine[i]=P-(P/i)*ine[P%i]%P,jcc[i]=jcc[i-1]*ine[i]%P;
for(i=m+2;i<=n;i++) f[i]=(i-m-1+s[i-1]-s[i-m-1]+P)*jc[i-2]%P,s[i]=(s[i-1]+f[i]*jcc[i-1])%P;
printf("%I64d",s[n]*jc[n-1]%P);
return 0;
}
【CF886E】Maximum Element DP的更多相关文章
- 【CF886E】Maximum Element
题目 考虑正难则反,答案即为\(n!-\text{返回值为n的排列数}\) 一个排列的返回值为\(n\),当且仅当在\(n\)出现之前没有一个数后面有连续\(k\)个小于它的数 设\(f_i\)表示\ ...
- 【CF888E】Maximum Subsequence(meet in the middle)
[CF888E]Maximum Subsequence(meet in the middle) 题面 CF 洛谷 题解 把所有数分一下,然后\(meet\ in\ the\ middle\)做就好了. ...
- 【CF888E】Maximum Subsequence 折半搜索
[CF888E]Maximum Subsequence 题意:给你一个序列{ai},让你从中选出一个子序列,使得序列和%m最大. n<=35,m<=10^9 题解:不小心瞟了一眼tag就一 ...
- 【题解】POJ1934 Trip (DP+记录方案)
[题解]POJ1934 Trip (DP+记录方案) 题意: 传送门 刚开始我是这么设状态的(谁叫我DP没学好) \(dp(i,j)\)表示钦定选择\(i\)和\(j\)的LCS,然而你会发现这样钦定 ...
- 【题解】剪纸条(dp)
[题解]剪纸条(dp) HRBUST - 1828 网上搜不到题解?那我就来写一篇吧哈哈哈 最优化问题先考虑\(dp\),设\(dp(i)\)表示将前\(i\)个字符(包括\(i\))分割成不相交的回 ...
- 【题解】地精部落(DP)
[题解]地精部落(DP) 设\(f_i\)表示强制第一个是谷的合法方案数 转移枚举一个排列的最大值在哪里,就把序列分成了互不相干的两个部分,把其中\(i-1\choose j-1\)的数字分配给前面部 ...
- 【BZOJ2213】[Poi2011]Difference DP
[BZOJ2213][Poi2011]Difference Description A word consisting of lower-case letters of the English alp ...
- 【BZOJ-1068】压缩 区间DP
1068: [SCOI2007]压缩 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 1001 Solved: 615[Submit][Status][ ...
- 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 3396 Solved: 1434[Submit][Sta ...
随机推荐
- UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改
lienhua342014-09-10 1 文件访问权限 在文件访问权限和进程访问控制中,我们已经讲述过文件访问权限位,为了方便,我们重新列在下面, 表 1: 文件的 9 个访问权限位 st_mod ...
- How to use base class's assignment operator in C++
看了android下的代码,好长时间没看了,有个关于C++的知识点不是很清楚,查了下: 如何使用基类中的赋值运算符? 引述自http://stackoverflow.com/questions/122 ...
- 安装yeoman报没有权限的错误
新的ubuntu服务器, 不小心先装了npm, 再装的node, 再用meanjs装的yeoman(即不是自己npm install -g yo装的, 是用meanjs的stack一步到位的),而正常 ...
- Android学习之——ListView下拉刷新
背景知识 ListView使用非常广泛,对于使用ListView的应用来说,下拉刷新是必不可少要实现的功能. 我们常用的微博.网易新闻,搜狐新闻都使用了这一功能,如下图所示. 微博 搜狐新闻 ...
- VS2015常用快捷键
1.回到上一个光标位置/前进到下一个光标位置 1)回到上一个光标位置:使用组合键“Ctrl + -”: 2)前进到下一个光标位置:“Ctrl + Shift + - ”. 2.复制/剪切/删除整行代 ...
- [Arch] 02. Design principle and Software Pattern
Ref: 软件设计的七大原则 有时间的话,还需进一步深入理解. Figure, 重要的前五个原则 单一职责原则 (Simple responsibility pinciple SRP) 类的设计趋向于 ...
- 让你的应用支持新iPad的Retina显示屏
一.应用图片标准iOS控件里的图片资源,苹果已经做了相应的升级,我们需要操心的是应用自己的图片资源.就像当初为了支持iPhone 4而制作的@2x高分辨率版本(译者:以下简称高分)图片一样,我们要为i ...
- flexbox父盒子align-content属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- osgExp只能将3dmax中的动画导出为路径动画osg::AnimationPath,而不能导出osgAnimation::Animation。osg播放骨骼动画应该使用FBX格式
通过实际的模型测试,导出为.osg文本格式,搜索animation,只能搜索到AnimationPathCallback,而搜索不到osgAnimation相关类 在OSGExp1.5.0源代码中搜索 ...
- [SublimeText] 如何创建工程
Sublime Text 可以很方便地管理多个工程.使用Sublime Text的Projects,可以将不同根目录的文件组织起来成为一个工程,而不用将所有的文件都放到一个根目录下面. 1. 创建工程 ...