有n個木塊排成一行,從左到右依次編號爲1~n。你有k種顏色的油漆,其中第i種顏色的油漆足夠塗ci個木塊。
全部油漆恰好足夠塗滿全部木塊,即c1+c2+...+ck=n。相鄰兩個木塊塗相同色顯得很難看,因此你但願統計任意兩
個相鄰木塊顏色不一樣的着色方案。ios
有n個木塊排成一行,從左到右依次編號爲1~n。你有k種顏色的油漆,其中第i種顏色的油漆足夠塗ci個木塊。
全部油漆恰好足夠塗滿全部木塊,即c1+c2+...+ck=n。相鄰兩個木塊塗相同色顯得很難看,因此你但願統計任意兩
個相鄰木塊顏色不一樣的着色方案。ios
第一行爲一個正整數k,第二行包含k個整數c1, c2, ... , ck。spa
輸出一個整數,即方案總數模1,000,000,007的結果。code
100%的數據知足:1 <= k <= 15, 1 <= ci <= 5blog
/* 直接狀態壓縮是顯然是不可行的,咱們考慮若是沒有相鄰顏色不相同的限制的話, 若是兩種油漆能染的木塊數目相同,咱們就能夠認爲兩種油漆無差異。 設dp[a1][a2][a3][a4][a5]爲能染1個木塊的油漆有a1種……的方案數。 可是有相鄰顏色的限制,若是上一次用了顏色數爲last的油漆, 那麼這一次有一種顏色數爲last-1的油漆就不能用了,轉移的時候注意一下。 */ #include<iostream> #include<cstdio> #define mod 1000000007 #define lon long long using namespace std; int s[6],dp[16][16][16][16][16][16],k; int dfs(int a1,int a2,int a3,int a4,int a5,int last){ if(dp[a1][a2][a3][a4][a5][last]) return dp[a1][a2][a3][a4][a5][last]; if(a1+a2+a3+a4+a5==0) return dp[a1][a2][a3][a4][a5][last]=1; lon tot=0; if(a1) tot+=1LL*(a1-(last==2))*dfs(a1-1,a2,a3,a4,a5,1),tot%=mod; if(a2) tot+=1LL*(a2-(last==3))*dfs(a1+1,a2-1,a3,a4,a5,2),tot%=mod; if(a3) tot+=1LL*(a3-(last==4))*dfs(a1,a2+1,a3-1,a4,a5,3),tot%=mod; if(a4) tot+=1LL*(a4-(last==5))*dfs(a1,a2,a3+1,a4-1,a5,4),tot%=mod; if(a5) tot+=1LL*a5*dfs(a1,a2,a3,a4+1,a5-1,5),tot%=mod; return dp[a1][a2][a3][a4][a5][last]=tot; } int main(){ scanf("%d",&k); for(int i=1;i<=k;i++){ int x;scanf("%d",&x); s[x]++; } printf("%d",dfs(s[1],s[2],s[3],s[4],s[5],0)); return 0; }