題目:
There is a fence with n posts, each post can be painted with one of the k colors.java
You have to paint all the posts such that no more than two adjacent fence posts have the same color.post
Return the total number of ways you can paint the fence.spa
Note:
n and k are non-negative integers.code
解答:
這道題其實跟house rob很相似,用dp作的時候在function部分很容易寫錯,當取跟前面不同的顏色時,這一輪一共有除了前面這個顏色的k-1個顏色能夠選;當取跟前面同樣的顏色的時候,這一輪只有一種狀況能夠選,且:前一輪不能取跟前前一輪同樣的顏色,不然這三個post的顏色就都相同了,不符合題中說的最多兩個相鄰的post顏色相同。代碼以下:it
public class Solution { //State: f[i][j] is total number of ways we can paint the fence; //Function: f[i][0] = f[i - 1][0] * k - 1 + f[i - 1][1] * (k - 1) // f[i][1] = f[i - 1][0] + f[i - 1][1] //Initialize: f[0][0] = k, f[0][1] = k; f[1][0] = k * (k - 1), f[1][1] = k; //Result: f[n - 1][0] + f[n - 1][1]; public int numWays(int n, int k) { if (n == 0 || k == 0) return 0; if (n == 1) return k; int[][] f = new int[n][2]; //Initialize f[0][1] = f[1][1] = k; f[0][0] = k; f[1][0] = k * (k - 1); //f[i][0]表示跟前面不同顏色,f[i][1]表示跟前面同樣顏色 for (int i = 2; i < n; i++) { //跟前面不同顏色的話,在這輪有k - 1種可能性 f[i][0] = f[i - 1][0] * (k - 1) + f[i - 1][1] * (k - 1); //跟前面同樣顏色的話,在這輪有1種可能性,且前一輪不能與前前一輪同樣顏色 f[i][1] = f[i - 1][0]; } return f[n - 1][0] + f[n - 1][1]; } }
由於這個dp的解法裏,咱們只用到變量i - 1和i,因此咱們能夠進定步把空間複雜度降爲o(1):io
//Save space to O(1) because it only cares about i - 1 and i public int numWays(int n, int k) { if (n == 0 || k == 0) return 0; if (n == 1) return k; int diff = k * (k - 1); int same = k; for (int i = 2; i < n; i++) { int tmp = diff; diff = (diff + same) * (k - 1); same = tmp; } return same + diff; }