zoukankan      html  css  js  c++  java
  • 【CF285E】Positions in Permutations

    题目

    刷水题涨信心

    显然这是个广义容斥,我们现在算一下至少有(i)个完美数的方案数就好了

    (1000)的数据范围显然在暗示(n^2)的dp

    我们注意到这个条件大概就是(P_i=i-1)(P_i=i+1),于是我们可以想象成左右两边各(n)个点去完成一个一一匹配

    (dp[i][j][k][p])表示左边第(i)个数已经匹配完了,一共形成了(j)对完美数,(k)表示右边对应的第(i)个位置的使用状态(0/1)(p)表示右边第(i+1)个数的使用状态

    转移显然

    代码

    #include<cstdio>
    #define re register
    const int mod=1e9+7;
    const int maxn=1005;
    int n,m,tot;
    int dp[maxn][maxn][2][2],ans[maxn];
    int c[maxn][maxn],fac[maxn];
    int main() {
    	scanf("%d%d",&n,&m);fac[0]=1;
    	for(re int i=0;i<=n;i++) c[i][0]=c[i][i]=1;
    	for(re int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
    	for(re int i=2;i<=n;i++)
    		for(re int j=1;j<i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    	dp[1][0][0][0]=1,dp[1][1][0][1]=1;
    	for(re int i=1;i<n;i++)
    		for(re int j=0;j<=i;j++)
    			for(re int k=0;k<2;k++)
    				for(re int p=0;p<2;p++) {
    					if(!dp[i][j][k][p]) continue;
    					dp[i+1][j+1][p][1]=(dp[i+1][j+1][p][1]+dp[i][j][k][p])%mod;
    					if(!k) dp[i+1][j+1][p][0]=(dp[i+1][j+1][p][0]+dp[i][j][k][p])%mod;
    					dp[i+1][j][p][0]=(dp[i+1][j][p][0]+dp[i][j][k][p])%mod;
    				}
    	for(re int i=0;i<=n;i++)
    		ans[i]=(dp[n][i][0][0]+dp[n][i][1][0])%mod;
    	for(re int j=m;j<=n;j++) 
    		tot=(tot+1ll*((j-m)&1?-1:1)*c[j][m]*fac[n-j]%mod*ans[j]%mod)%mod;
    	printf("%d
    ",(tot+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    MongoDB
    Redis主从复制
    在Flash中动画的制作方式:
    帧的类型:
    第一次做的补间动画,总结过程
    Python脚本:过滤取指定链接标题是否含有指定文字,并将其输出
    cmd命令:在ftp下载文件运行
    bat命令:在txt文本每行后加指定文字
    bat命令:在txt文本每行前加指定文字
    SSH爆破心得:
  • 原文地址:https://www.cnblogs.com/asuldb/p/10926580.html
Copyright © 2011-2022 走看看