AtCoder Grand Contest 030 (AGC030) F - Permutation and Minimum 动态规划

原文链接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;
}
posted @ 2019-06-05 08:08  zzd233  阅读(327)  评论(0编辑  收藏  举报