# bzoj1079[SCOI2008]着色方案

### 题目链接

bzoj1079[SCOI2008]着色方案

### 题解

dp[a][b][c][d][e][last]

last表示上次转移的种类

### 代码

#include<cstdio>
#include<algorithm>
int x = 0,f = 1;
char c = getchar();
while(c <= '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
#define LL long long
const int mod = 1e9 + 7;
const int maxn = 19;
LL dp[maxn][maxn][maxn][maxn][maxn][7];
LL dfs(int a,int b,int c,int d,int e,int last) { //last 安放改点的等价类与上次等价类变化后相同，减掉
if(!a && !b && !c && !d && !e) return 1;
if(dp[a][b][c][d][e][last]) return dp[a][b][c][d][e][last];
LL ret = 0;
if(a) ret +=dfs(a - 1,b,c,d,e,1) * (a - (last == 2)) ;
ret %= mod;
if(b) ret +=dfs(a + 1,b - 1,c,d,e,2) * (b - (last == 3)) ;
ret %= mod;
if(c) ret +=dfs(a ,b + 1,c - 1,d,e,3) * (c - (last == 4)) ;
ret %= mod;
if(d) ret +=dfs(a,b,c + 1,d - 1,e,4) * (d - (last == 5)) ;
ret %= mod;
if(e) ret +=dfs(a,b,c,d + 1,e - 1,5) * e ;// 上次等价类已经转移纸last - 1
ret %= mod;
return dp[a][b][c][d][e][last] = ret;
}
int C[maxn];
int main() {