1079: [SCOI2008]着色方案

链接

思路

  首先是dp,如果直接用每个种颜色的剩余个数做状态的话,复杂度为5^15。

  由于c<=5,所以用剩余数量的颜色的种类数做状态:f[a][b][c][d][e][last]表示剩余数量为1的颜色种类数,为2,3,4,5的。

  转移时,如果上一次使用的是为4的,这次如果转移使用3的话,为了使相邻的不相同,则需要-1

  最后一个转移写错了个地方,一直re...

代码

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 
 5 using namespace std;
 6 typedef long long LL;
 7 const LL mod = 1e9+7;
 8 const int N = 16;
 9 
10 LL f[N][N][N][N][N][6];
11 int t[6];
12 
13 LL dfs(int a,int b,int c,int d,int e,int last) {
14     if ((a|b|c|d|e)==0) return 1;
15     if (f[a][b][c][d][e][last]) return f[a][b][c][d][e][last];
16     LL ans = 0;
17     if (a) ans += dfs(a-1,b,c,d,e,1)*(a-(last==2));
18     if (ans > mod) ans %= mod;
19     if (b) ans += dfs(a+1,b-1,c,d,e,2)*(b-(last==3));
20     if (ans > mod) ans %= mod;
21     if (c) ans += dfs(a,b+1,c-1,d,e,3)*(c-(last==4));
22     if (ans > mod) ans %= mod;
23     if (d) ans += dfs(a,b,c+1,d-1,e,4)*(d-(last==5));
24     if (ans > mod) ans %= mod;
25     if (e) ans += dfs(a,b,c,d+1,e-1,5)*e; //-
26     if (ans > mod) ans %= mod;
27     f[a][b][c][d][e][last] = ans;
28     return ans;
29 }
30 
31 int main() {
32     int n;
33     cin >> n;
34     for (int a,i=1; i<=n; ++i) {
35         cin >> a;
36         t[a] ++;
37     }
38     cout << dfs(t[1],t[2],t[3],t[4],t[5],0);
39     return 0;
40 }

 

posted @ 2018-04-17 20:38  MJT12044  阅读(122)  评论(0编辑  收藏  举报