博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF285E Positions in Permutations(dp+容斥)
阅读量:6241 次
发布时间:2019-06-22

本文共 1566 字,大约阅读时间需要 5 分钟。

题意,给定n,k,求有多少排列是的 | p[i]-i |=1 的数量为k。

Solution

直接dp会有很大的后效性。

所以我们考虑固定k个数字使得它们是合法的,所以我们设dp[i][j][0/1][0/1]表示前i个数,填了j个数,当前位置有没有被选,下一位有没有被选,这样做的话,转移会比较简单。

那么除去这j个数,剩下的数随便填,乘上全排列就好了。

但这样会多算。

然后这种问题有一个容斥模型,直接套上就好了。

#include
#include
#define N 1002using namespace std;typedef long long ll;int n,k;ll dp[N][N][2][2],jie[N],ni[N],g[N],ans;const int mod=1e9+7;ll calc(int n,int m){ return jie[n]*ni[m]%mod*ni[n-m]%mod;}ll power(ll x,int y){ ll ans=1; while(y){ if(y&1)(ans*=x)%=mod; (x*=x)%=mod; y>>=1; } return ans;}int main(){ scanf("%d%d",&n,&k);jie[0]=1; for(int i=1;i<=n;++i)jie[i]=(jie[i-1]*i)%mod;ni[n]=power(jie[n],mod-2); for(int i=n-1;i>=0;--i)ni[i]=ni[i+1]*(i+1)%mod; dp[0][0][1][0]=1; for(int i=1;i<=n;++i){ for(int j=0;j<=n;++j){ dp[i][j][0][0]=(dp[i-1][j][0][0]+dp[i-1][j][1][0])%mod; dp[i][j][1][0]=(dp[i-1][j][0][1]+dp[i-1][j][1][1])%mod; if(j){ (dp[i][j][0][0]+=dp[i-1][j-1][0][0])%=mod; dp[i][j][0][1]+=(dp[i-1][j-1][0][0]+dp[i-1][j-1][1][0])%mod; dp[i][j][0][1]%=mod; (dp[i][j][1][0]+=dp[i-1][j-1][0][1])%=mod; dp[i][j][1][1]+=(dp[i-1][j-1][0][1]+dp[i-1][j-1][1][1])%mod; dp[i][j][1][1]%=mod; } } } for(int i=k;i<=n;++i) g[i]=(dp[n][i][0][0]+dp[n][i][1][0])%mod*jie[n-i]%mod; for(int i=k;i<=n;++i)(ans+=(((i-k)&1)?-1:1)*calc(i,k)*g[i]%mod+mod)%=mod; ans=(ans+mod)%mod; cout<

 

转载于:https://www.cnblogs.com/ZH-comld/p/9896870.html

你可能感兴趣的文章
红帆iOffice HD上线14天,Store排行榜第27位,商业类NO.1.
查看>>
我的友情链接
查看>>
nginx+django+uwsgi部署配置
查看>>
关于HWM的一些测试
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
以太坊中的gas、gas price、gas limit到底是什么
查看>>
用户配置文件服务登录失败。无法加载用户配置文件
查看>>
com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0
查看>>
我的友情链接
查看>>
四则运算法则表延伸 - 工厂方法模式
查看>>
我的友情链接
查看>>
话里话外:企业管理的五个层次
查看>>
Hazelcast集群服务(3)
查看>>
研究人员创建可***BIOS和网卡的恶意软件
查看>>
C++ numeric_limits的用法
查看>>
升级maildrop,解决自动回复乱码问题
查看>>
MySQL Sandbox---快速体验各版本MySQL
查看>>
我的友情链接
查看>>
CentOS安装KDE和Gnome
查看>>