zoukankan      html  css  js  c++  java
  • AtCoder Grand Contest 030 (AGC030) F

    原文链接www.cnblogs.com/zhouzhendong/p/AGC030F.html

    草率题解

    对于每两个相邻位置,把他们拿出来。

    如果这两个相邻位置都有确定的值,那么不管他。

    然后把所有的这些数拿出来,分为两类,一类是没有被填入的,一类是被填入的。

    然后大力DP即可。由于没有被填入的可以任意排列,所以最后还要乘上一个阶乘。

    代码

    #include <bits/stdc++.h>
    #define clr(x) memset(x,0,sizeof x)
    #define For(i,a,b) for (int i=(a);i<=(b);i++)
    #define Fod(i,b,a) for (int i=(b);i>=(a);i--)
    #define fi first
    #define se second
    #define pb(x) push_back(x)
    #define mp(x,y) make_pair(x,y)
    #define outval(x) cerr<<#x" = "<<x<<endl
    #define outtag(x) cerr<<"---------------"#x"---------------"<<endl
    #define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";
    						For(_x,L,R)cerr<<a[_x]<<" ";cerr<<endl;
    using namespace std;
    typedef long long LL;
    typedef vector <int> vi;
    LL read(){
    	LL x=0,f=0;
    	char ch=getchar();
    	while (!isdigit(ch))
    		f|=ch=='-',ch=getchar();
    	while (isdigit(ch))
    		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return f?-x:x;
    }
    const int N=305*2,mod=1e9+7;
    int Pow(int x,int y){
    	int ans=1;
    	for (;y;y>>=1,x=(LL)x*x%mod)
    		if (y&1)
    			ans=(LL)ans*x%mod;
    	return ans;
    }
    void Add(int &x,int y){
    	if ((x+=y)>=mod)
    		x-=mod;
    }
    void Del(int &x,int y){
    	if ((x-=y)<0)
    		x+=mod;
    }
    int Add(int x){
    	return x>=mod?x-mod:x;
    }
    int Del(int x){
    	return x<0?x+mod:x;
    }
    int n;
    int a[N],b[N];
    int cnt=0,tot=0;
    int dp[N][N][N];
    vector <int> v;
    int main(){
    	n=read();
    	For(i,1,n*2){
    		a[i]=read();
    		if (a[i]!=-1)
    			b[a[i]]=1;
    	}
    	For(i,1,n){
    		if (a[i*2-1]==-1&&a[i*2]==-1)
    			cnt++,tot+=2;
    		else if (a[i*2-1]==-1)
    			tot+=2,v.pb(a[i*2]);
    		else if (a[i*2]==-1)
    			tot+=2,v.pb(a[i*2-1]);
    	}
    	For(i,1,n*2)
    		if (!b[i])
    			v.pb(i);
    	sort(v.begin(),v.end());
    	v.pb(0);
    	reverse(v.begin(),v.end());
    	dp[0][0][0]=1;
    	For(i,1,tot)
    		For(j,0,tot)
    			For(k,0,tot){
    				int val=dp[i-1][j][k];
    				if (!val)
    					continue;
    				if (!b[v[i]]){
    					Add(dp[i][j+1][k],val);
    					if (j>0)
    						Add(dp[i][j-1][k],val);
    					if (k>0)
    						Add(dp[i][j][k-1],(LL)val*k%mod);
    				}
    				else {
    					Add(dp[i][j][k+1],val);
    					if (j>0)
    						Add(dp[i][j-1][k],val);
    				}
    			}
    	int ans=dp[tot][0][0];
    	For(i,1,cnt)
    		ans=(LL)ans*i%mod;
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    拷贝构造函数与赋值运算符的区别(待完善)
    概念学习(Concept Learning)
    函数对象适配器之ptr_fun的使用示例
    SynchronizationContext的研究之一(非WPF及Forms)
    ESLint
    Vue CLI 4.0 关于 webpack 基本配置范例
    Hdu3787
    Cf393A
    Cf387A
    Cf386B
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/AGC030F.html
Copyright © 2011-2022 走看看