【BZOJ1079】著色方案
阿新 • • 發佈:2018-11-02
題目連結:https://www.lydsy.com/JudgeOnline/problem.php?id=1079
吼題啊!
自己做,不會做,看完題解分析,不會寫程式碼,看完程式碼自己寫,交上去報錯,複製題解程式碼交上去,通過。
類似於中國象棋,這道題也涉及合併本質相同的狀態。最簡單的思路是,設dp[a1][a2]...[ak][last]表示第幾種顏色還剩幾次可以使用,上一次用的是什麼顏色的方案數。顯然會炸,實際上,我們只關心還可以用幾次的顏色有幾種,並不關心具體是哪種顏色,剛好,每種顏色可以使用的次數並不多。設dp[a][b][c][d][e][l]表示還可用1次的顏色有a種,2次的有b種,...,上一次用的是剩餘l次的顏色,注意是上一次用之前剩l次,對於當前是剩l-1次的某種顏色。然後討論接下來選擇剩幾次的顏色即可,注意剩l+1次的顏色會少一種選擇。
1 #include <cstdio> 2 #include <cstring> 3 4 typedef long long ll; 5 6 const int maxk = 16, maxc = 6, mod = 1e9 + 7; 7 8 int rest[maxc]; 9 ll dp[maxk][maxk][maxk][maxk][maxk][maxc]; 10 11 ll dfs(int a, int b, int c, int d, int e, int l) { 12 ll& f = dp[a][b][c][d][e][l];AC程式碼13 if (f != -1) return f; 14 if (a + b + c + d + e == 0) return 1; 15 ll t = 0; 16 if (a) t += (a - (l == 2)) * dfs(a - 1, b, c, d, e, 1); 17 if (b) t += (b - (l == 3)) * dfs(a + 1, b - 1, c, d, e, 2); 18 if (c) t += (c - (l == 4)) * dfs(a, b + 1, c - 1, d, e, 3); 19 if(d) t += (d - (l == 5)) * dfs(a, b, c + 1, d - 1, e, 4); 20 if (e) t += e * dfs(a, b, c, d + 1, e - 1, 5); 21 return f = t % mod; 22 } 23 24 int main() { 25 int k, c; 26 scanf("%d", &k); 27 for (int i = 1; i <= k; ++i) { 28 scanf("%d", &c); 29 ++rest[c]; 30 } 31 memset(dp, -1, sizeof(dp)); 32 printf("%lld", dfs(rest[1], rest[2], rest[3], rest[4], rest[5], 0)); 33 return 0; 34 }