有n个木块排成一行,从左到右依次编号为1~n。你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块。
所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n。相邻两个木块涂相同色显得很难看,所以你希望统计任意两
个相邻木块颜色不同的着色方案。 k<=15,c<=5
f[a][b][c][d][e][l] a-e表示剩余1-5个块的颜色的数量,l表示上一个选的颜色,记忆化搜索。
#include<iostream> #include<cstdio> #define mod 1000000007 #define ll long long #define g f[s1][s2][s3][s4][s5][last] using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } ll f[16][16][16][16][16][6]; int c[16],K,num[6]; ll dfs(int s1,int s2,int s3,int s4,int s5,int last) { if(g)return g; if(s1)g+=(s1-(last==1))*dfs(s1-1,s2,s3,s4,s5,0); if(s2)g+=(s2-(last==2))*dfs(s1+1,s2-1,s3,s4,s5,1); if(s3)g+=(s3-(last==3))*dfs(s1,s2+1,s3-1,s4,s5,2); if(s4)g+=(s4-(last==4))*dfs(s1,s2,s3+1,s4-1,s5,3); if(s5)g+=s5*dfs(s1,s2,s3,s4+1,s5-1,4); g%=mod; return g; } int main() { K=read();for(int i=1;i<=K;i++)c[i]=read(),num[c[i]]++; for(int i=0;i<5;i++)f[0][0][0][0][0][i]=1; cout<<dfs(num[1],num[2],num[3],num[4],num[5],0); return 0; }