1. 程式人生 > >Thatcher學計算機

Thatcher學計算機

從物理學到計算機,再到硬體,再到人工智慧! 藍橋杯備賽 (LintCode上刷的第三題)

問題描述

我們有一個柵欄,它有n個柱子,現在要給柱子染色,有k種顏色可以染。 必須保證不存在超過2個相鄰的柱子顏色相同,求有多少種染色方案。

樣例輸出

n = 3, k = 2, return 6 在這裡插入圖片描述

問題分析

最開始,我想用動態陣列儲存每一種方案的第i根柱子的顏色。後來發現這樣資料量太大,而且記錄也很困難。最後轉換思路,用dp[i]表示到第i根柱子時有多少種塗色方案。這樣就很容易就實現了。 dp[i]和dp[i + 1]表示分別到前面兩根柱子時的塗色方案。 首先賦初值:dp[0] = k;dp[1] = k * k; 如果dp[i] == dp[i + 1],說明前面兩根柱子顏色相同,則dp[i + 3] = (k - 1) * dp[i + 2];如果dp[i] != dp[i + 1],說明前面兩根柱子顏色不相同,則dp[i + 3] = (k - 1) * dp[i + 1]。 因為此段時間一直在刷動態規劃的題,所以一般都採用動態規劃來求解!

JAVA實現程式碼

package DP;

public class PostColored514_1111 {

	/**
	 * 根據不超過兩個相鄰柱子的顏色相同的規則,求出有多少中染色方案
	 * @param n 有多少根柱子
	 * @param k 有多少種顏色
	 * @return
	 */
	public static int postColored(int n, int k) {
		// 沒有柱子時,沒有塗色方案
		if (n == 0) {
			return 0;
		}
		// 當只有一根柱子時,有多少種顏色就有多少種方案
		if (n == 1) {
			return k;
		}
		// 建立一個數組dp,dp[i]表示前i根柱子有多少種塗色方案
		int[] dp = new int[n];
		if (n == 2) {
			return k * k;
		} else {
			// 第一根柱子有k種塗色方案
			dp[0] = k;
			//到第二根柱子,有k * k種染色方案
			dp[1] = k * k;
			//遍歷剩下的柱子
			for (int i = 2; i < n; i++) {
				//當前兩根柱子染色不同時,第三根柱子的染色情況為dp[i - 1] * (k - 1)
				//當前兩根柱子染色相同時,第三根柱子的染色情況為dp[i - 2] * (k - 1)
				dp[i] = dp[i - 1] * (k - 1) + dp[i - 2] * (k - 1);
			}
		}

		return dp[n - 1];
	}

	public static void main(String[] args) {
		int n = 3, k = 2;
		System.out.println(postColored(n, k));
	}
}