`
Vitas_Wang
  • 浏览: 9807 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

动态规划算法学习

阅读更多
给定待粉刷的n个墙砖(排成一行),每个墙砖可以粉刷的颜色种类为:红、蓝、绿、黄,问粉刷完毕后,红色墙砖和蓝色墙砖都是偶数的粉刷方式有多少种(结果对10007取余).

题目解析:
首先题目问红色和蓝色都是偶数的粉刷方式,由此可以得出,其他的刷黄刷绿无所谓,都可以。因此可以把颜色分为红,蓝,其它。
题目只关注奇偶,不关注具体红蓝各刷了多少块,因此我们也只分奇偶即可。
很显然前面n-1块砖的粉刷方式会对第n次粉刷的结果产生影响,由此我想这应该是一个动态规划问题。
第n块粉刷后的结果取决于第n-1块的结果,第n-1块的结果取决于n-2,... ... , 第2块的粉刷结果取决于第1块的结果。
只刷一块可能的粉刷方式是:
1》刷一块绿或黄,这样红,蓝都是偶数;两种刷法,刷绿,刷黄;
结果为2;
此时考虑粉刷2块的情况:
当第一块刷按方式1》刷时,为了得到偶数红蓝,第二块只能刷绿黄, 所以有四种刷法;
但这并不是最终结果,因为可以刷两块红,也是正解;
第二块的结果还依赖于第一块的非正确结果,我们分析只刷一块的所有结果:
2》刷一个蓝,这样红是偶数,蓝是奇数,一种刷法; 此时第二块只能刷蓝,一种刷法。
3》刷一块红,这样红是奇数,蓝是偶数,一种刷法; 此时第二块只能刷红,一种刷法。
(红,蓝) 结果, (偶, 偶),(奇, 偶), (偶, 奇)
我们马上联想到还应有一个(奇, 奇), 只是在只刷一块时这种可能性为0;

由此可得刷两块时结果为4+1+1 = 6;
但当刷三块时,结果又依赖于刷两块时的其它结果;
刷两块的所有可能结果为(偶,偶)(偶,奇)(奇,偶)(奇,奇)
由此我们来推断通用表达式:设a[i-1]为第i-1块刷完后结果为(偶,偶)的刷法,b[i-1]为(偶,奇)结果,同理c[i-1],d[i-1]
a[i] = 2a[i-1]+b[i-1]+c[i-1]+0d[i-1];
b[i] = a[i-1] + 2b[i-1] + 0c[i-1] + d[i-1];
c[i] = a[i-1] + 0b[i-1] + 2c[i-1] + d[i-1];
d[i] = 0a[i-1]+ b[i-1] + c[i-1] + 2d[i-1];
相信到这里大家都可以写出答案了,稍后时间整理代码和大家交流。

public class BrushWall {
	public static int base = 10007;
	public static int[][] Multi(int[][] a, int[][] b){
		int[][] result = new int[a.length][b[0].length];
		for(int i = 0; i < result.length; i++){
			for(int j = 0; j < result[0].length; j++){
				result[i][j] = 0;
			}
		}
		for(int i = 0; i < a.length; i++){
			for(int j = 0; j < b[0].length; j++){
				for(int k = 0; k < a[i].length; k++){
					result[i][j] += a[i][k]*b[k][j];
				}
				result[i][j] %= 10007;
			}
		}
		return result;
	}
	public static void printMatrix(int[][] data){
		for(int i = 0; i < data.length; i++){
			for(int j = 0; j < data[0].length; j++){
				System.out.print(data[i][j] + " ");
			}
			System.out.println();
		}
	}
	
	public static void initMatrix(int[][] data){
		for(int i = 0; i < data.length; i++){
			for(int j = 0; j < data[0].length; j++){
				data[i][j] = 0;
				if(i == j){
					data[i][j] = 1;
				}
			}
		}
	}
	public static void matrixAdd(int[][] a, int[][] b){
		for(int i = 0; i < a.length; i++){
			for(int j = 0; j < a[0].length; j++){
				a[i][j] += b[i][j];
			}
		}
	}
	public static int[][] pow(int[][] a, int n){
		int[][] result = new int[a.length][a[0].length];
		initMatrix(result);
		while(n > 0){
			if((n & 1) != 0) result = Multi(result, a);
			a = Multi(a, a);
			n >>= 1;
		}
		return result;
	}
	public static void main(String[] args){
		int[][] matrix = new int[][]{{2, 1, 1, 0},{1, 2, 0, 1},{1, 0, 2, 1},{0, 1, 1, 2}};
		int number = 2;
		if(number == 1) {
			System.out.println("There have " + 2 + " way to brush the wall");
			return;
		}
		int[][] result = pow(matrix, 1);
		int methods = 2*result[0][0] + result[1][0] + result[2][0];
		System.out.println("There have " + methods + " way to brush the wall");
	}
}

分享到:
评论

相关推荐

    动态规划算法学习十例之七

    在这个“动态规划算法学习十例之七”的主题中,我们将聚焦于一个具体的动态规划问题——最长公共子序列(Longest Common Subsequence,简称LCS)。这个问题在计算机科学中具有很高的实用价值,尤其是在比较和分析...

    动态规划算法学习十例之九

    在这个“动态规划算法学习十例之九”的主题中,我们将聚焦于如何通过DP来解决实际问题。尽管描述部分没有提供具体的实例,但从标题来看,我们可以推测这是一个关于动态规划应用的系列教程的第九个例子。 动态规划的...

    动态规划算法学习十例之六

    在这个主题“动态规划算法学习十例之六”中,我们将探讨如何利用动态规划方法来解决实际问题。博文链接虽然未提供具体内容,但我们可以根据提供的文件名推测讨论的是一个具体的编程实例。 `Main.java`通常是一个...

    动态规划算法学习十例之五

    标题中的“动态规划算法学习十例之五”表明这篇内容主要关注的是计算机科学中的动态规划算法,这是一种在解决复杂问题时非常有效的优化方法。动态规划通常用于处理具有重叠子问题和最优子结构的问题,通过将大问题...

    动态规划算法学习十例之四

    在这个“动态规划算法学习十例之四”的主题中,我们将专注于背包问题的解决方案。背包问题是一个经典的计算机科学问题,它通常涉及在给定容量的背包中选择物品以最大化总价值。 首先,我们来了解动态规划的基本思想...

    动态规划算法学习十例之一

    在这个“动态规划算法学习十例之一”的主题中,我们将会探讨动态规划的基本概念和一个具体的实例,通过分析`Test.java`源码来深入理解。 首先,动态规划的核心思想是将一个大问题分解为相互重叠的小问题,并通过...

    动态规划算法的应用

    "动态规划算法的应用" 动态规划算法是一种非常强大且广泛应用的算法思想,它可以解决许多复杂的问题。动态规划算法的核心思想是将问题分解...在未来的学习和工作中,我们将继续掌握和应用动态规划算法来解决实际问题。

    leetcode算法题主函数如何写-Dynamic-Programming-Note:动态规划算法学习心得(leetcode)

    动态规划算法学习心得(leetcode) 动态规划算法的实质是更好的优化穷举算法,即把算过的子树记录下来减少计算次数。 储存计算过的子树的数列就是dp数列 使用动态规划有三个条件 1.最值问题 一般动态规划的使用场景是...

    matlab实现动态规划算法 程序源码.zip

    【达摩老生出品,必属...资源名:matlab实现动态规划算法 程序源码.zip 资源类型:程序源代码 源码说明: 基于matlab实现动态规划的程序,包含完整源码和注释,非常适合借鉴学习 适合人群:新手及有一定经验的开发人员

    动态规划学习动态规划算法

    学习动态规划算法

    AOVAOE网络 动态规划算法PPT学习教案.pptx

    AOVAOE网络 动态规划算法PPT学习教案.pptx

    学习电脑信息五大常用算法之二:动态规划算法

    "学习电脑信息五大常用算法之二:动态规划算法" 动态规划算法是五大常用算法之一,是解决多阶段决策问题的有效方法。它的基本思想是将问题分解为多个阶段,每个阶段都有其状态和决策,然后通过决策序列来解决问题。...

    动态规划算法介绍算法介绍

    本资源“动态规划算法介绍”旨在为ACM竞赛和算法初学者提供一个理解和应用动态规划的良好起点,帮助扩展解题思路。 动态规划的核心思想是将复杂问题分解为多个子问题,并通过存储和重用子问题的解决方案来避免重复...

    动态规划算法笔记总结ZIP分享

    动态规划是一种重要的算法思想,广泛应用于解决复杂优化问题。它通过将大问题分解为相互关联的小问题,并存储每个小问题的解,避免了重复计算,从而达到高效求解的目的。在计算机科学,尤其是算法设计中,动态规划是...

    DP算法即动态规划算法集锦

    标题中的“DP算法即动态规划算法集锦”,暗示我们将探讨一系列动态规划的经典案例,这些案例可能包括但不限于背包问题、最长公共子序列、最短路径问题、字符串匹配等。动态规划能够处理具有重叠子问题和最优子结构的...

    动态规划算法及其一些例子

    标题中的“动态规划算法及其一些例子”意味着我们将探讨动态规划的基本原理,并通过具体的例子来加深理解。动态规划通常有以下三个关键步骤: 1. **定义状态**:明确表示问题的中间阶段,例如,斐波那契数列中的第n...

    动态规划算法详解(ACM编程培训)

    动态规划算法通常涉及到一个最优决策序列的问题,它通过自底向上的方式求解,将原问题分解为子问题,通过填充一个表格(也称为状态转移表)来逐步构建出最优解。在这个过程中,每个子问题的解都会被记录下来,以便...

    动态规划算法(学习算法分析二)

    这个压缩包文件“动态规划算法(学习算法分析二)”显然包含了一系列与动态规划相关的学习资源,包括源代码和作者的心得体会。下面,我们将深入探讨动态规划的基本概念、应用场景以及相关知识点。 动态规划的核心思想...

    C++ 动态规划算法实现0-1背包问题

    总的来说,这个C++实现的0-1背包问题动态规划算法不仅展示了如何利用动态规划解决问题,还提供了代码调试和测试的方法,是学习和理解动态规划算法的一个优秀实例。通过深入研究和实践,我们可以掌握这一重要的算法...

    贪心算法和动态规划算法题解.7z

    贪心算法和动态规划是两种在计算机科学中广泛使用的算法设计策略,特别是在解决优化问题时。这两种方法在处理复杂问题时各有特点,但都致力于找到全局最优解。 贪心算法是一种局部最优解策略,它每次选择当前状态下...

Global site tag (gtag.js) - Google Analytics