瓷砖铺放问题题解友情链接
瓷砖问题再讨论
例如,长度为4的地面一共有如下4种铺法,并且,一共用了长度为1的瓷砖4块:
4=1+2+1
4=1+3
4=2+2
4=3+1
编程求解上述问题。
第二行也有一个数,代表这些铺法中长度为1的瓷砖的总数
4
4
题目分析:递归问题+数学问题(其实最后发现尝试用动态规划也可以叭啦啦~)
算法分析:一开始吧,我也没想到动态规划这回事,就先暴力手写,列出前几个情况呗:
我们把第一块为长度为1的瓷砖的方案数用红色表示,其他方案用绿色表示。(不要纠结为什么选这两个颜色,耀眼呗,就是耀眼!) 好的,现在引入二维数组way[ ][ ],way[ i ][ 1 ]表示长度为i且第一块为长度为1的瓷砖的方案数(红的那些),way[ i ][ 0 ]当然就表示长度为i且第一块为长度不为1的瓷砖的方案数了(绿的那些)。看出什么门道了呢,就是way[ i ][ 1 ] = way[ i - 1 ][ 0 ],那么 way[ i ][ 0 ]呢,我还是决定继续徒眼找(就是不信邪,总觉得应该是简单题,想暴力一把)。有意思的是,就这么给看出来了,于是我把看出点的规律整理成式子,也就是way[i][0] = way[i - 2][0] + way[i - 2][1] + way[i - 3][0] + way[i - 3][1] 。
但是问题中还要求输出长度为1的瓷砖总数,那就再引入数组num[ ][ ] ,继续找呗,这时候光靠看已经有点费劲了,于是把两个数组的前几种情况列下来,大同小异,规律是num[i][1] = way[i][1] + num[i - 1][0] 和 num[i][0] = num[i - 2][0] + num[i - 2][1] + num[i - 3][0] + num[i - 3][1]。可以对照下面研究。
算法设计:
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
sc.close();
int[][] way = new int[11][2];
int[][] num = new int[11][2];
way[1][0] = way[2][1] = 0;
way[1][1] = way[2][0] = way[3][1] = 1;
way[3][0] = 2;
for (int i = 4; i <= 10; i++) {
way[i][0] = way[i - 2][0] + way[i - 2][1] + way[i - 3][0] + way[i - 3][1];
way[i][1] = way[i - 1][0];
}
num[1][0] = num[2][1] = num[2][0] = 0;
num[1][1] = num[3][1] = num[3][0] = 1;
for (int i = 4; i <= 10; i++) {
num[i][0] = num[i - 2][0] + num[i - 2][1] + num[i - 3][0] + num[i - 3][1];
num[i][1] = way[i][1] + num[i - 1][0];
}
int ways = way[N][0] + way[N][1];
int nums = num[N][0] + num[N][1];
System.out.println(ways);
System.out.println(nums);
}
}
Emmmmm.....程序没有错,但是我们需要反思一下,这两组动态规划状态式的本质是什么,毕竟不是很多题目可以这样找出规律的,深思熟路了很久,大概想通了。但是鉴于我的第一篇k好数——动态规划入门题解,写得实在是太久太详细了,耗时耗力,这里的动态规划不再做深入解析,动态规划都是要靠悟出来的,多思考当然是好的是吧。还没有入门的这里再放个友情链接叭。
博客探讨了1024瓷砖问题的解决方案,通过递归和数学分析,提出使用动态规划的方法来求解。文章介绍了动态规划的状态转移方程,并展示了如何通过观察和归纳得出这些方程。虽然给出了程序实现,但强调动态规划的理解和应用需要深入思考。

被折叠的 条评论
为什么被折叠?



