bzoj 1079: [SCOI2008]着色方案
思路:按个数分类dp
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define piii pair<int, pair<int,int> > 8 9 using namespace std; 10 11 const int N = 16; 12 const int M = 10 + 7; 13 const int inf = 0x3f3f3f3f; 14 const LL INF = 0x3f3f3f3f3f3f3f3f; 15 const int mod = 1e9 + 7; 16 17 int n, cur, sum, num[6]; 18 int dp[2][6][N][N][N][N][N]; 19 20 void add(int &a, int b) { 21 a += b; if(a >= mod) a-= mod; 22 } 23 int main() { 24 scanf("%d", &n); 25 for(int i = 1; i <= n; i++) { 26 int x; scanf("%d", &x); 27 num[x]++; 28 sum += x; 29 } 30 dp[cur][0][num[1]][num[2]][num[3]][num[4]][num[5]] = 1; 31 32 for(int i = 0; i < sum; i++) { 33 cur ^= 1; 34 for(int j = 0; j <= 5; j++) 35 for(int a = 0; a <= n; a++) 36 for(int b = 0; b <= n; b++) 37 for(int c = 0; c <= n; c++) 38 for(int d = 0; d <= n; d++) 39 for(int e = 0; e <= n; e++) 40 dp[cur][j][a][b][c][d][e] = 0; 41 42 for(int j = 0; j <= 5; j++) { 43 for(int a = 0; a <= n; a++) { 44 for(int b = 0; b <= n; b++) { 45 for(int c = 0; c <= n; c++) { 46 for(int d = 0; d <= n; d++) { 47 for(int e = 0; e <= n; e++) { 48 if(!dp[cur ^ 1][j][a][b][c][d][e]) continue; 49 if(e) { 50 LL cnt = e - (5 == j); 51 add(dp[cur][4][a][b][c][d + 1][e - 1], 1ll * dp[cur ^ 1][j][a][b][c][d][e] * cnt % mod); 52 } 53 54 if(d) { 55 LL cnt = d - (4 == j); 56 add(dp[cur][3][a][b][c + 1][d - 1][e], 1ll * dp[cur ^ 1][j][a][b][c][d][e] * cnt % mod); 57 } 58 59 if(c) { 60 LL cnt = c - (3 == j); 61 add(dp[cur][2][a][b + 1][c - 1][d][e], 1ll * dp[cur ^ 1][j][a][b][c][d][e] * cnt % mod); 62 } 63 64 if(b) { 65 LL cnt = b - (2 == j); 66 add(dp[cur][1][a + 1][b - 1][c][d][e], 1ll * dp[cur ^ 1][j][a][b][c][d][e] * cnt % mod); 67 } 68 69 if(a) { 70 LL cnt = a - (1 == j); 71 add(dp[cur][0][a - 1][b][c][d][e], 1ll * dp[cur ^ 1][j][a][b][c][d][e] * cnt % mod); 72 } 73 } 74 } 75 } 76 } 77 } 78 } 79 } 80 int ans = dp[cur][0][0][0][0][0][0]; 81 printf("%d\n", ans); 82 return 0; 83 } 84 /* 85 */