还是可以想出来的题目 不过考场上没有想出来 要 引以为戒。

初看觉得有点不可做 10分给到了爆搜。

考虑第一个特殊情况 B排列为1~m.

容易发现A排列中前m个数字 他们之间不能产生交换 且 第k个数字要交换到后面的m+1~n这些数字的时候 k~m的数字都要进行交换才行。

那么直接枚举有多少个数字到后面了 组合数可以解决 考虑剩下的那些空位怎么办。

其实就是要求出 \(f_i\) 其表示满足题目条件的i个数的排列的个数.

考虑递推 容易发现\(f_0=1,f_1=1\) 对于\(f_i\)考虑第i个数字不换 那么为\(f_{i-1}\)换的话有i-1种方法 对应的方案为\((i-1)\cdot f_{i-2}\)

综上可以得到\(f_i=f_{i-1}+(i-1)\cdot f_{i-2}\)

这样结合上面的dfs就可以获得30分了。

考虑另外一种递推的模型 可以发现m在第一个 那么就要想办法将m换到第一个。

显然 m可以不动 那么剩下的m-1个数字就要放到后面了。

m可以直接和1交换 那么剩下的m-2个数字要放到后面。

m还可以和后面的进行交换 其实就是m个数字放到后面。

三种情况分别讨论即可。结合上面的两种方法就可以得到50分了。具体细节看代码。

上午也只推到这里。因为感觉正解比较难 所以就每有一直探索下去 其实可以继续走下去。

考虑正解:综上其实可以发现 m个数全部扔到后面是一定合法的,那么其实就是考虑有多少个数字可以被扔到前面。

如果有k个数字在后面 那么前面这s=m-k个数字就应该在前面 且他们不能和后面的k个数字存在交换。

这样就要求他们是一个合法排列 容易想到合法情况最多只有一种 这点容易证明。

也就是说此时只需要判断s个数字放到前面是否合法 即满足题目中的条件。

可以暴力安排位置 因为第一个要放到数值最小的位置上去 这样暴力放然后再check即可。

复杂度\(m^2+n\)

code
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-8
#define sq sqrt
#define mod 1000000007
#define S second
#define F first
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=30010,maxn=10000010;
int n,m,ans;
int a[MAXN],b[MAXN];
int vis[MAXN],f[maxn],fac[maxn],inv[maxn];
inline int ksm(int b,int p)
{
int cnt=1;
while(p)
{
if(p&1)cnt=(ll)cnt*b%mod;
b=(ll)b*b%mod;p=p>>1;
}
return cnt;
}
inline void dfs(int x)
{
if(x==n+1)
{
int cnt=1;
rep(1,n,i){if(a[a[i]]!=i)return;if(a[i]==b[cnt])++cnt;}
if(cnt>m)
{
++ans;
//rep(1,n,i)cout<<a[i]<<' ';
//cout<<endl;
}
return;
}
rep(1,n,i)
{
if(vis[i])continue;
a[x]=i;vis[i]=1;
dfs(x+1);
vis[i]=0;
}
}
inline int C(int a,int b){return (ll)fac[a]*inv[b]%mod*inv[a-b]%mod;}
inline int check()
{
rep(2,m,i)if(b[i]!=i-1)return 0;
return 1;
}
inline void prepare()
{
f[0]=1;fac[0]=1;
rep(1,n,i)
{
fac[i]=(ll)fac[i-1]*i%mod;
f[i]=(f[i-1]+(ll)f[i-2]*(i-1))%mod;
}
inv[n]=ksm(fac[n],mod-2);
fep(n-1,0,i)inv[i]=(ll)inv[i+1]*(i+1)%mod;
}
int main()
{
freopen("1.in","r",stdin);
//freopen("ya.out","w",stdout);
get(n);get(m);int flag=0;
if(n<m){put(0);return 0;}
rep(1,m,i)
{
get(b[i]);
if(b[i]!=i)flag=1;
}
if(n<=10)
{
dfs(1);put(ans);
return 0;
}
prepare();
if(m==1){put(f[n]);return 0;}
if(n==m)
{
rep(1,m,i)if(b[b[i]]!=i){put(0);return 0;}
put(1);return 0;
}
if(!flag)
{
int ww=min(m,n-m);
rep(0,ww,i)ans=(ans+(ll)C(n-m,i)*f[n-m-i])%mod;
put(ans);return 0;
}
if(b[1]==m&&check())
{
if(n>=2*m-2)//和1交换.
ans=(ll)f[n-2*m+2]*C(n-m,m-2)%mod;
if(n>=2*m-1)//不动.
ans=(ans+(ll)f[n-2*m+1]*C(n-m,m-1))%mod;
if(n>=2*m)//交换.
ans=(ans+(ll)f[n-2*m]*C(n-m,m))%mod;
put(ans);
}
else
{
if(n>=2*m)ans=(ans+(ll)f[n-2*m]*C(n-m,m))%mod;
rep(1,m,i)//枚举前m个位置
{
if(n<2*m-i)continue;
int flag=0,ww=0;
vis[b[i]]=1;
rep(1,i,j)
{
++ww;
while(!vis[ww])++ww;
a[b[j]]=ww;
}
rep(1,m,j)if(vis[j]&&a[a[j]]!=j){flag=1;break;}
if(!flag)ans=(ans+(ll)f[n-2*m+i]*C(n-m,m-i))%mod;
//cout<<flag<<endl;
}
put(ans);
}
return 0;
}

7.1 NOI模拟赛 计数问题 dp的更多相关文章

  1. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  2. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  3. [10.18模拟赛] 序列 (DP)

    [10.18模拟赛] 序列 题目描述 山山有一个整数序列s1,s2,-,sn,其中1≤si≤k. 求出有多少个准确移除m个元素后不同的序列.答案模(1e9+7) 输入 输入包括几个测试用例,并且由文件 ...

  4. 7.12 NOI模拟赛 生成树 装压dp vector装压

    LINK:生成树 这场比赛我打的真失败 T3是比较容易的 却一直刚 那道"数论" 10分其实搜一下全排列. 30分容易想到对边进行装压dp. 不过存在一些细节 可以对于一个连通块的 ...

  5. 7.12 NOI模拟赛 探险队 期望 博弈 dp 最坏情况下最优策略 可并堆

    LINK:探险队 非常难的题目 考试的时候爆零了 完全没有想到到到底怎么做 (当时去刚一道数论题了. 首先考虑清楚一件事情 就是当前是知道整张地图的样子 但是不清楚到底哪条边断了. 所以我们要做的其实 ...

  6. 7.11 NOI模拟赛 graph 生成函数 dp 多项式

    LINK:graph HDU题库里的原题 没做过自闭. 考虑dp 设\(f_{i,j}\)表示前i个点构成j个联通块是树的方案数. 对于一次询问答案即为\(\sum_{j}f_{n,j}j^k\) 考 ...

  7. 7.1 NOI模拟赛 dp floyd

    这是一道非常垃圾的题目 且 数据范围简直迷惑选手.. 可以发现 题目中有 边权递增 边的条数 所有边权值不同 最小边权和等条件. 看起来很难做 一个想法 边权递增+边的1的权值都不相同可以想到 关系存 ...

  8. 7.9 NOI模拟赛 C.走路 背包 dp 特异性

    (啊啊啊 什么考试的时候突然降智这题目硬生生没想出来. 容易发现是先走到某个地方 然后再走回来的 然后在倒着走的路径上选择一些点使得最后的得到的最多. 设\(f_{i,j}\)表示到达i这个点选择的价 ...

  9. NOI 模拟赛 #2

    得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...

随机推荐

  1. 移动端H5页面_input获取焦点时,虚拟键盘挡住input输入框解决方法

    在移动端h5开发的时候,发现如果input在页面底部,当触发input焦点的时候会弹出系统虚拟键盘,虚拟键盘会遮挡input输入框.这会很影响用户体验,于是在网上找到了如下的解决办法: 方法一:使用w ...

  2. Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

    1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...

  3. Java嵌套类,内部类和外部类

    1.嵌套类,内部类 嵌套类是指被定义在一个类内部的类: JAVA的嵌套类有很多种类:1.静态成员类:2.非静态成员类:3.匿名类:4.局部类:其中,除了静态成员类之外,其他的都是内部类,因为静态成员类 ...

  4. P3295 萌萌哒 题解

    题目 一个长度为n的大数,用\(S_1,S_2,S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,\(l_1 ...

  5. Traffic Real Time Query System 圆方树+LCA

    题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...

  6. Spring 5.2.x 源码环境搭建(Windows 系统环境下)

    前期准备 1.确保本机已经安装好了 Git 2.Jdk 版本至少为 1.8 3.安装好 IntelliJ IDEA (其他开发工具,如 eclipse.Spring Tool Suite 等也是可以的 ...

  7. 树莓派4B踩坑指南 - (16)外接4k显示器的相关设置

    最近某宝新买了个4k显示器, 总价700多, 质量凑合, 就把树莓派接上来了, 这一下苦了眼睛了, 于是有了此番调整 1. 先解决4k下60帧的刷新率 在\boot\config.txt的末尾加入一条 ...

  8. cookie与token

    cookie: 登陆后后端生成一个sessionid放在cookie中返回给客户端,并且服务端一直记录着这个sessionid,客户端以后每次请求都会带上这个sessionid, 服务端通过这个ses ...

  9. 接口测试框架实战(三)| JSON 请求与响应断言

    关注公众号,获取测试开发实战干货合辑.本文节选自霍格沃兹<测试开发实战进阶>课程教学内容. 数据驱动就是通过数据的改变驱动自动化测试的执行,最终引起测试结果的改变.简单来说,就是参数化在自 ...

  10. [C++面向对象]-C++成员函数和非成员函数

    大纲: 1.成员函数和非成员函数 2.详细解释 3.总结 4.参考   1.成员函数和非成员函数   其实简单来说成员函数是在类中定义的函数,而非成员函数就是普通函数,即不在类中定义的函数,其中非成员 ...