http://www.lydsy.com/JudgeOnline/problem.php?id=1079
看了范围以为是搜索,直到我发现了“即方案总数模1,000,000,007的结果。”
一类不容易想到状态的DP,和ZJOI???有点像,比那个简单就是了
看了题解的状态表示,我自己写了个dp,结果写错了。。。。。
我好弱啊啊啊啊啊啊啊啊啊
//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int getint()
{
int r=0,k=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
return k*r;
}
/
#define mod 1000000007;
int n,k;
int c[6];
LL dp[16][16][16][16][16][6];//前i个 a,b,c,e,d
/
LL DP(int a,int b,int c,int d,int e,int k)
{
LL &ans=dp[a][b][c][d][e][k];
if(~ans) return ans;
if(a+b+c+d+e==0) return ans=1;
ans=0;
if(a) ans+=(a-(k==2))*DP(a-1,b,c,d,e,1);
if(b) ans+=(b-(k==3))*DP(a+1,b-1,c,d,e,2);
if(c) ans+=(c-(k==4))*DP(a,b+1,c-1,d,e,3);
if(d) ans+=(d-(k==5))*DP(a,b,c+1,d-1,e,4);
if(e) ans+=(e)*DP(a,b,c,d+1,e-1,5);
return ans%=mod;
}
/
void input()
{
k=getint();
int x;
rep(i,1,k) x=getint(),c[x]++;
}
void solve()
{
MS(dp,-1);
printf("%lld\n",DP(c[1],c[2],c[3],c[4],c[5],0));
}
/
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.out","w",stdout);
#endif
input(),
solve();
return 0;
}