【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 }

 

 
posted @ 2017-03-10 22:31  嘘丶  阅读(212)  评论(0编辑  收藏  举报