2018.10.20 bzoj1079: [SCOI2008]著色方案(多維dp)
阿新 • • 發佈:2018-12-16
傳送門 dp妙題。 表示還剩下個可以用一次的,還剩下個可以用兩次的,還剩下個可以用三次的,還剩下個可以用四次的,還剩下個可以用五次的時候的方案數。 再次強調:狀態真是妙啊。 注意到如果這次選可以用i次的,上一次選的是可以用i+1次的這一次的轉移係數要減1。 因為上一次那種可以用次的這一次只能用次了,所以轉移時不能用這一種來轉移。 程式碼:
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n,f[16][16][16][16][16][6],cnt[6];
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
inline int dfs(int a,int b,int c,int d,int e,int las){
if(~ f[a][b][c][d][e][las])return f[a][b][c][d][e][las];
if(!(a|b|c|d|e))return f[a][b][c][d][e][las]=1;
f[a][b][c][d][e][las]=0;
if(a)(f[a][b][c][d][e][las]+=(long long)(a-(las==2))*dfs(a-1,b,c,d,e,1)%mod)%=mod;
if(b)(f[a][b][c][d][e][las]+=(long long)(b-(las==3))*dfs(a+1,b-1,c,d,e,2)%mod)%=mod;
if( c)(f[a][b][c][d][e][las]+=(long long)(c-(las==4))*dfs(a,b+1,c-1,d,e,3)%mod)%=mod;
if(d)(f[a][b][c][d][e][las]+=1ll*(d-(las==5))*dfs(a,b,c+1,d-1,e,4)%mod)%=mod;
if(e)(f[a][b][c][d][e][las]+=1ll*e*dfs(a,b,c,d+1,e-1,5)%mod)%=mod;
return f[a][b][c][d][e][las];
}
int main(){
memset(f,-1,sizeof(f)),scanf("%d",&n);
for(int i=1;i<=n;++i)++cnt[read()];
cout<<dfs(cnt[1],cnt[2],cnt[3],cnt[4],cnt[5],0);
return 0;
}