http://www.lydsy.com/JudgeOnline/problem.php?id=1079
Can only think of the practice of the 5^15 ..... ........... Sure enough, I'm too weak.
In fact, it should be not the use of good topic information, ci<=5!
Then we can consider the remaining lattice of the color as an equivalence class!
That is, the state of the f[a,b,c,d,e] means that there are 1 of the color of a type of lattice, the remaining 2 of the color of the lattice B ... In turn. So when the shift
F[A,B,C,D,E]=A*F[A-1,B,C,D,E]+B*F[A+1,B-1,C,D,E]+C*F[A,B+1,C-1,D,E]+...+E*F[A,B,C,D+1,E-1]
But we found that we did not consider the adjacent situation? It's okay! We can add one dimension!
We add another dimension, indicating that the last use of the color is the equivalent of a class last, then this time when the calculation is not adjacent, then this time put last-1 the color of one less, so is A-1 or b-1 or .... or e-1 and then multiply the f behind.
Then the shift becomes:
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]
And last==6 meaningless, can be removed.
Then the memory of the search can be.
That's a good question!
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream > #include <algorithm> #include <queue> #include <set> #include <map>using namespace std; typedef long Long LL; #define REP (i, n) for (int i=0; i< (n); ++i) #define FOR1 (i,a,n) for (int i= (a); i<= (n); ++i) #define For2 (i,a,n) for (int i= (a);i< (n), ++i) #define FOR3 (i,a,n) for (int i= (a); i>= (n); i.) #define FOR4 (i,a,n) for (int i= ( a);i> (n); i) #define CC (i,a) memset (i,a,sizeof (i)) #define READ (a) a=getint () #define PRINT (a) printf ("%d", a) # Define DBG (x) cout << (#x) << "=" << (x) << endl#define error (x) (! x) puts ("error"): 0) #define RDM (x, i) for (int i=ihead[x]; i; i=e[i].next) inline const int Getint () {int r=0, k=1; Char c=g Etchar (); for (; c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') k=-1; for (; c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) r=r*10+c-' 0 '; return k*r; }const ll Md=1000000007;ll f[17][17][17][17][17][6];ll dp (int A, INT B, int c, int d, int e, int last) {if ((a|b|c|d|e) ==0) return 1;if (F[a][b][c][d][e][last]) return F[a][b][c][d][e][last] ; ll Ret=0;if (a) RET+=DP (A-1, B, C, D, E, 1) * (A-(last==2)), if (b) RET+=DP (a+1, B-1, C, D, E, 2) * (b-(last==3)); if (c) RET+=DP ( A, b+1, C-1, D, E, 3) * (c (last==4)), if (d) RET+=DP (A, B, c+1, D-1, E, 4) * (d (last==5)); if (e) RET+=DP (A, B, C, d+1, e-1, 5) * E;return F[A][B][C][D][E][LAST]=RET%MD;} int A[6];int Main () {int n=getint (); For1 (i, 1, N) a[getint ()]++;p rintf ("%lld\n", DP (A[1], a[2], a[3], a[4], a[5], 0)); Retu RN 0;}
Description
There are n pieces of wood lined up, numbered from left to right in 1~n. You have a k color of paint, wherein the first color of the paint is enough to tu ci a wood block. All the paint is just enough to fill all the pieces of wood, namely c1+c2+...+ck=n. Adjacent two pieces of wood painted the same color looks very ugly, so you want to count any two adjacent wood color different coloring scheme.
Input
The first behavior is a positive integer k, the second line contains k integers c1, c2, ..., CK.
Output
Outputs an integer, which is the result of modulo 1,000,000,007 for the total number of scenarios.
Sample INPUT3
1 2 3Sample Output10hint
100% of data meet: 1 <= k <=, 1 <= ci <= 5
Source
"Bzoj" 1079: [SCOI2008] Coloring scheme (dp+ special tricks)