514. 栅栏染色

从物理学到计算机,再到硬件,再到人工智能!
蓝桥杯备赛 (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));
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值