题目来源:http://www.lintcode.com/zh-cn/problem/paint-fence/
题目描述
有一个栅栏,它有n个柱子,现在要给柱子染色,有k种颜色可以染。不能有连续三个柱子颜色相同,求有多少种染色方案。(lintcode描述错误)
翻译
任何一个柱子的颜色,只与它上一个柱子和上上个柱子的颜色有关。假设有柱子1,2,3
- 如果1和2的颜色相同,那么3的颜色必须和1,2不同;
- 如果1和2的颜色不同,那么3的颜色就与1和2没关系了;
样例
n = 3, k = 2, return 6
post 1, post 2, post 3
way1 0 0 1
way2 0 1 0
way3 0 1 1
way4 1 0 0
way5 1 0 1
way6 1 1 0
思路 = 动态规划
第一个柱子的染色方案有:dp[1] = k
第二个柱子的染色方案有:dp[2] = k * k
第三个柱子的染色方案:
- 如果第三个柱子和第二个柱子颜色相同,那么第一个柱子肯定与二,三颜色不同,则染色方案有dp[1] * (k - 1);
- 如果第三个柱子和第二个柱子颜色不同,则与第一个柱子颜色无关,则染色方案有dp[2] * (k - 1);
第四个柱子的染色方案:
- 如果第四个柱子和第三个柱子颜色相同,那么第二个柱子肯定与三,四颜色不同,则染色方案有dp[2] * (k - 1);
- 如果第四个柱子和第三个柱子颜色不同,则与第二个柱子颜色无关,则染色方案有dp[3] * (k - 1);
…
第n个柱子的染色方案
- 如果第n个柱子和第n-1个柱子颜色相同,那么第n-2个柱子肯定与n-1,n颜色不同,则染色方案有dp[n-2] * (k - 1);
- 如果第n个柱子和第n-1个柱子颜色不同,则与第n-2个柱子颜色无关,则染色方案有dp[n-1] * (k - 1);
由以上可以得出状态转移方程:dp[n] = (dp[n - 1] + dp[n - 2]) * (k - 1)
code
class Solution {
public:
/**
* @param n non-negative integer, n posts
* @param k non-negative integer, k colors
* @return an integer, the total number of ways
*/
int numWays(int n, int k) {
// Write your code here
if (n <= 0 || k <= 0) {
return 0;
}
if (n == 1) {
return k;
}
if (n > 2 && k == 1) { // 多个栅栏,但是k = 1
return 0;
}
int n1 = k;
int n2 = k * k;
for (int i = 2; i < n; i++) {
int tmp = n1 * (k-1) + n2 * (k - 1);
n1 = n2;
n2 = tmp;
}
return n2;
}
};
请尊重作者的劳动,转载请注明作者及原文地址(http://blog.csdn.net/lis_12/article/details/55212759).
如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。