zoukankan      html  css  js  c++  java
  • arc093F Dark Horse

    我们可以假设1的位置在1,并且依次与右边的区间合并。答案最后乘上2^n即可。

    那么需要考虑1所在的区间与另一个区间合并时,另一个区间的最小值不能为特殊的。

    直接求解很难,考虑容斥,钦定在哪几个位置必定输,容斥出必胜的方案数。

    从大到小dp,设f(i,S)表示当前考虑到第i个特殊的数,必输的区间集合为S。

    考虑是否向集合S中加入i,若加入,枚举在哪个区间合并,用组合数算出能够选出的数的方案并乘上排列数。

    若不加入,则直接转移即可。

    f(i,S) <- f(i+1,S)

    f(i,S|(1<<k)) <- Σ f(i+1,S) * C((1<<n)-S-a[i],(1<<k)-1) * (1<<k)!

    最后f(i,S)对答案的贡献还要乘上没有钦定的位置数的排列。

    最后答案乘上2^n。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=17,mod=1e9+7;
    int n,m,a[N],f[N][1<<N],fac[1<<N],ifac[1<<N];
    int Pow(int x,int k){
    	int ret=1;
    	while(k){
    		if(k&1)ret=(ll)ret*x%mod;
    		k>>=1;x=(ll)x*x%mod;
    	}
    	return ret;
    }
    int C(int n,int m){
    	if(n<m)return 0;
    	return (ll)fac[n]*ifac[m]%mod*ifac[n-m]%mod;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)scanf("%d",&a[i]);
    	fac[0]=1;
    	for(int i=1;i<=(1<<n);i++)fac[i]=(ll)fac[i-1]*i%mod;
    	for(int i=0;i<=(1<<n);i++)ifac[i]=Pow(fac[i],mod-2);
    	sort(a+1,a+m+1,greater<int>());
    	f[0][0]=1;
    	for(int i=0;i<m;i++)
    		for(int j=0;j<(1<<n);j++){
    			if(!f[i][j])continue;
    			f[i+1][j]=(f[i+1][j]+f[i][j])%mod;
    			int res=(1<<n)-j-a[i+1];
    			for(int k=0;k<n;k++){
    				if(j&(1<<k))continue;
    				if(res<(1<<k)-1)break;
    				f[i+1][j|(1<<k)]=(f[i+1][j|(1<<k)]-(ll)f[i][j]*C(res,(1<<k)-1)%mod*fac[1<<k])%mod;
    			}
    		}
    	int ans=0;
    	for(int i=0;i<(1<<n);i++){
    		ans=(ans+(ll)f[m][i]*fac[(1<<n)-1-i])%mod;
    	}
    	ans=((ll)ans*(1<<n)%mod+mod)%mod;
    	cout<<ans<<"
    ";
    }
    
  • 相关阅读:
    web服务器-Apache
    nginx优化
    nginx下载限速
    nginx-URL重写
    HDU 5358 First One 求和(序列求和,优化)
    HDU 5360 Hiking 登山 (优先队列,排序)
    HDU 5353 Average 糖果分配(模拟,图)
    UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
    HDU 5348 MZL's endless loop 给边定向(欧拉回路,最大流)
    HDU 5344 MZL's xor (水题)
  • 原文地址:https://www.cnblogs.com/Trrui/p/10314779.html
Copyright © 2011-2022 走看看