给定待粉刷的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) 动态规划算法的实质是更好的优化穷举算法,即把算过的子树记录下来减少计算次数。 储存计算过的子树的数列就是dp数列 使用动态规划有三个条件 1.最值问题 一般动态规划的使用场景是...
【达摩老生出品,必属...资源名:matlab实现动态规划算法 程序源码.zip 资源类型:程序源代码 源码说明: 基于matlab实现动态规划的程序,包含完整源码和注释,非常适合借鉴学习 适合人群:新手及有一定经验的开发人员
学习动态规划算法
AOVAOE网络 动态规划算法PPT学习教案.pptx
"学习电脑信息五大常用算法之二:动态规划算法" 动态规划算法是五大常用算法之一,是解决多阶段决策问题的有效方法。它的基本思想是将问题分解为多个阶段,每个阶段都有其状态和决策,然后通过决策序列来解决问题。...
本资源“动态规划算法介绍”旨在为ACM竞赛和算法初学者提供一个理解和应用动态规划的良好起点,帮助扩展解题思路。 动态规划的核心思想是将复杂问题分解为多个子问题,并通过存储和重用子问题的解决方案来避免重复...
动态规划是一种重要的算法思想,广泛应用于解决复杂优化问题。它通过将大问题分解为相互关联的小问题,并存储每个小问题的解,避免了重复计算,从而达到高效求解的目的。在计算机科学,尤其是算法设计中,动态规划是...
标题中的“DP算法即动态规划算法集锦”,暗示我们将探讨一系列动态规划的经典案例,这些案例可能包括但不限于背包问题、最长公共子序列、最短路径问题、字符串匹配等。动态规划能够处理具有重叠子问题和最优子结构的...
标题中的“动态规划算法及其一些例子”意味着我们将探讨动态规划的基本原理,并通过具体的例子来加深理解。动态规划通常有以下三个关键步骤: 1. **定义状态**:明确表示问题的中间阶段,例如,斐波那契数列中的第n...
动态规划算法通常涉及到一个最优决策序列的问题,它通过自底向上的方式求解,将原问题分解为子问题,通过填充一个表格(也称为状态转移表)来逐步构建出最优解。在这个过程中,每个子问题的解都会被记录下来,以便...
而在动态规划的学习中,重点将放在如何定义问题的状态,推导出正确的状态转移方程,并通过合适的优化技巧(如空间优化)来提升算法性能。 掌握贪心算法和动态规划对于编程能力的提升至关重要。它们不仅在算法面试中...
这个压缩包文件“动态规划算法(学习算法分析二)”显然包含了一系列与动态规划相关的学习资源,包括源代码和作者的心得体会。下面,我们将深入探讨动态规划的基本概念、应用场景以及相关知识点。 动态规划的核心思想...
总的来说,这个C++实现的0-1背包问题动态规划算法不仅展示了如何利用动态规划解决问题,还提供了代码调试和测试的方法,是学习和理解动态规划算法的一个优秀实例。通过深入研究和实践,我们可以掌握这一重要的算法...