题目大意:n个木块排成一行,有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块。所有油漆刚好足够涂满所有木块。统计任意两个相邻木块颜色不同的着色方案。
分析:一开始又给想麻烦了...Ci只有5啊...直接开数组...然后乘法原理+加法原理,f[a,b,c,d,e,x]表示数量1..5的分别有a..e个,上一次选了x就好了。
代码:
/************************************************************** Problem: 1079 User: 1012haoyifan Language: C++ Result: Accepted Time:60 ms Memory:88628 kb ****************************************************************/ #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; #define MaxN 17 #define MaxL 7 #define mod 1000000007 int n,k; int s[MaxL]; long long f[MaxN][MaxN][MaxN][MaxN][MaxN][MaxL]; bool v[MaxN][MaxN][MaxN][MaxN][MaxN][MaxL]; long long dfs(int a,int b,int c,int d,int e,int x) { if (a+b+c+d+e==0) return 1; long long temp=0; if (v[a][b][c][d][e][x]) return f[a][b][c][d][e][x]; if (a) temp+=(a-(x==2))*dfs(a-1,b,c,d,e,1),temp%=mod; if (b) temp+=(b-(x==3))*dfs(a+1,b-1,c,d,e,2),temp%=mod; if (c) temp+=(c-(x==4))*dfs(a,b+1,c-1,d,e,3),temp%=mod; if (d) temp+=(d-(x==5))*dfs(a,b,c+1,d-1,e,4),temp%=mod; if (e) temp+=e*dfs(a,b,c,d+1,e-1,5),temp%=mod; v[a][b][c][d][e][x]=true; f[a][b][c][d][e][x]=temp; return f[a][b][c][d][e][x]; } void init() { int t; scanf("%d",&k); for (int i=1;i<=k;i++) { scanf("%d",&t); s[t]++;n+=t; } } int main() { init(); printf("%lld",dfs(s[1],s[2],s[3],s[4],s[5],0)); return 0; }