zoukankan      html  css  js  c++  java
  • test20181004 排列

    题意

    分析

    容斥公式的意义

    选了原图中(x(x geq i))条边的方案,重复了(inom{x}{i})次。
    有多加多减,所以就是那个式子。
    具体而言,对选了x条原图中的边的方案,总共加减了

    [sum_{i=0}^{x} inom{x}{i} cdot (-1)^{i}\ = (1 + (-1))^x = 0 ]

    这么多次。用二项式定理即可证明上述式子在x>0的情况下均为0。

    dp方程解释

    所谓选第i个点就是说选了i和i-1之间的这条边。

    代码

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #pragma GCC optimize ("O0")
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define LL ll
    #define p mod
    using namespace std;
    template<class T> inline T read(T&x)
    {
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    using ll = long long;
    constexpr int INF=0x7fffffff;
    
    constexpr int MAXN=2007,mod=998244353;
    int fac[MAXN];
    int g[MAXN],f[MAXN][MAXN][2];
    int up;
    
    int main()
    {
      freopen("permutation.in","r",stdin);
      freopen("permutation.out","w",stdout);
    	int n,k;
    	read(n);read(k);
    	fac[0]=1;
    	for(int i=1;i<=n;++i)
    		fac[i] = (ll)fac[i-1] * i % mod;
    	g[0]=1;
    	for(int cs=1;cs<=2;++cs)
    	{
    		for(int i=1;i<=k;++i)
    		{
    			f[i][0][0]=1;
    			int j=i,tp=0;
    			for(;;)
    			{
    				if(j+k>n)
    					break;
    				j+=k,++tp;
    				for(int l=0;l<=tp;++l)
    				{
    					f[j][l+1][1] = f[j-k][l][0];
    					f[j][l][0] = (f[j-k][l][0] + f[j-k][l][1]) % mod;
    				}
    			}
    			for(int l=up;l>=0;--l)
    				for(int m=1;m<=tp;++m)
    					(g[l+m] += (ll)g[l] * (f[j][m][0] + f[j][m][1]) % mod) %= mod;
    			up+=tp;
    		}
    	}
    	int ans=0;
    	for(int i=0;i<=n;++i)
    	{
    		if(i&1)
    			(ans += mod - (ll)g[i] * fac[n-i] % mod) %= mod;
    		else
    			(ans += (ll)g[i] * fac[n-i] % mod) %= mod;
    	}
    	printf("%d
    ",ans);
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    Linux下批处理文件
    linux代码端启动终端
    ubuntu截图
    Ubuntu安装多个版本的Opencv
    Ubuntu双系统启动卡死
    Ubuntu14.04运行lsdslam与问题解决
    js懒加载
    公众号开发-获取用户信息
    ClipboardJS 复制文本功能
    css3 Gradient线性渐变详解
  • 原文地址:https://www.cnblogs.com/autoint/p/9743478.html
Copyright © 2011-2022 走看看