【SCOI2008】着色方案
题目:
http://oj.changjun.com.cn/problem/detail/pid/2027
考虑记忆化搜索。
因为每种颜色能涂的木块<=5,设f[a][b][c][d][e][last]代表当前还剩a个能涂1的木块......上一个涂的木块是剩last的木块
则f[a,b,c,d,e,last]=(a-(last==2))*f[a-1,b,c,d,e]+(b-(last==3))*f[a+1,b-1,c,d,e]+ (c-(last==4))*f[a,b+1,c-1,d,e]+...+( e(last==6))*f[a,b,c,d+1,e-1]。
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<ctime> 6 #include<cmath> 7 #include<string> 8 #include<vector> 9 #include<cstdio> 10 #include<cstdlib> 11 #include<cstring> 12 #include<iostream> 13 #include<algorithm> 14 #define LL long long 15 #define mod 1000000007 16 using namespace std; 17 int g[7],n=0,k; 18 LL f[17][17][17][17][17][7];//第六维判重 19 bool bj[17][17][17][17][17][7]; 20 LL dfs(int a,int b,int c,int d,int e,int Last) 21 { 22 if(a+b+c+d+e==0) return 1; 23 if(bj[a][b][c][d][e][Last]) return f[a][b][c][d][e][Last]%mod; 24 LL ans=0; 25 if(a) ans+=(a-(Last==2))*dfs(a-1,b,c,d,e,1),ans%=mod;//放a 26 if(b) ans+=(b-(Last==3))*dfs(a+1,b-1,c,d,e,2),ans%=mod;//放b 27 if(c) ans+=(c-(Last==4))*dfs(a,b+1,c-1,d,e,3),ans%=mod;//放c 28 if(d) ans+=(d-(Last==5))*dfs(a,b,c+1,d-1,e,4),ans%=mod;//放d 29 if(e) ans+=(e-(Last==6))*dfs(a,b,c,d+1,e-1,5),ans%=mod;//放e 30 f[a][b][c][d][e][Last]=ans%mod; 31 bj[a][b][c][d][e][Last]=1; 32 return ans%mod; 33 } 34 int main() 35 { 36 freopen("!.in","r",stdin); 37 freopen("!.out","w",stdout); 38 scanf("%d",&k); 39 int op; 40 for(int i=1;i<=k;i++) 41 scanf("%d",&op),g[op]++;//能涂op个的数量 42 dfs(g[1],g[2],g[3],g[4],g[5],0); 43 printf("%lld",f[g[1]][g[2]][g[3]][g[4]][g[5]][0]); 44 return 0; 45 }