zoukankan      html  css  js  c++  java
  • 【CF285E】Positions in Permutations(动态规划,容斥)

    【CF285E】Positions in Permutations(动态规划,容斥)

    题面

    CF
    洛谷

    题解

    首先发现恰好很不好算,所以转成至少,这样子只需要确定完一部分数之后剩下随意补。
    然后套一个二项式反演进行容斥就可以得到答案了。
    考虑怎么算至少(m)个的贡献,
    (f[i][j][S])表示当前填到了位置(i),一个有(j)个贡献,(i)(i+1)的使用情况是(S)的方案数,每次枚举一下这个位置是填(i+1)还是(i-1)还是其他就可以进行转移了。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MOD 1000000007
    #define MAX 1010
    void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int n,m,jc[MAX],a[MAX],ans;
    int f[MAX][MAX][4],C[MAX][MAX];
    int main()
    {
    	n=read();m=read();
    	jc[0]=1;for(int i=1;i<=n;++i)jc[i]=1ll*jc[i-1]*i%MOD;
    	for(int i=0;i<=n;++i)C[i][0]=1;
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=i;++j)
    			C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
    	f[0][0][1]=1;
    	for(int i=1;i<=n;++i)
    		for(int j=0;j<i;++j)
    			for(int S=0;S<4;++S)
    			{
    				if(!f[i-1][j][S])continue;
    				add(f[i][j][S>>1],f[i-1][j][S]);
    				if(!(S&1))add(f[i][j+1][S>>1],f[i-1][j][S]);
    				if(i!=n)add(f[i][j+1][(S>>1)|2],f[i-1][j][S]);
    			}
    	for(int i=0;i<=n;++i)
    		for(int S=0;S<4;++S)
    			add(a[i],1ll*f[n][i][S]*jc[n-i]%MOD);
    	for(int i=m,d=1;i<=n;++i,d=MOD-d)add(ans,1ll*d*C[i][m]%MOD*a[i]%MOD);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    网页简单布局之结构与表现原则(HTML/CSS)
    浅谈搜索引擎SEO(HTML/CSS)
    Vue小案例(一)
    vue2.0中的计算属性
    Vue.js双向绑定原理
    Vue实例对象的数据选项(火柴)
    基于Vue的WebApp项目开发(六)
    基于Vue的WebApp项目开发(五)
    基于Vue的WebApp项目开发(四)
    基于Vue的WebApp项目开发(三)
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10926265.html
Copyright © 2011-2022 走看看