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 }