ACM 递推专题

1.1161-XTUOJ 

现在用1*2的骨牌,去铺n*3的地板,骨牌可以竖着和横着放,但不能重叠,请问铺满地板一共有多少种不同的铺法?

输入

每行输入一个整数n,(1≤n≤1,000),如果n为0表示样例输入结束,这个样例不用处理。由于结果可能很大,所以需要将结果对100,003取模。

输出

每行输出一个样例的结果。

样例输入
1
2
3
4
1000
0
样例输出
0
3
0
11
74979

考点:递推,画图找关系

易错:数据精度大,容易溢出。

分析:

骨牌铺方格问题由来已久,我们先回顾一下比较基础的版本。

杭电OJ 骨牌铺方格

这道题的分析要从画图开始,做三步操作:

(1)画图。(至少考察三种情况)

(2)把得出每个图的方法分类。

(3)找递推关系。

      我们把n=2、n=3、n=4的图画出来后可以发现,图分为两类,一类是最后一列是竖列,那么f[n-1]是排列好的,另一种是最后两列都是横列,那么f[n-2]排列好的。至此,我们就可以大概猜想出规律了。

好,有了这道题的基础,下面我们来分析这道题目。

      我们还是从特殊情况出发入手分析题目。我们发现,当n为奇数的时候,答案应该为0。那么n为偶数时,画出他们来。

     我们分别画出n=2,n=4的情况。当n等于4时,我们很清楚的可以发现,总共11种情况,可以分成11=9+2。其中的9种是把3X4的方块切割成两个2X3的情况,设f[n]为铺nX3的地板的铺法种数,那么此时有f[4]=f[2]*f[2],那么还有两种是怎么来的呢?

       从最后两种图的形式大概可以看出来,图不是f[2]*f[2]的情况,它不均匀。现在来考虑一下f[n]的情况。根据前面的经验,我们可以把这个图先切割来看,可以分为f[2]*f[n-2]、f[4]*f[n-4]、f[6]*f[n-6]....在加上一些不均匀的情况,那么仔细分析可以发现,其中一定会有重复的情况,接下来分析一下如何去重。对于分类f[4]*f[n-4],f[4]不能直接分成f[2]*f[2]来算,我们应该找出其中不能被竖线再分割的情况,我们挑任意n来分析。

       我们知道,第一列肯定只能有两种情况,上面是横向矩形,下面是竖向矩形或者上面是竖向下面是横向,我们先考虑第一种情况。由题意,我们不能被竖线切割,那么竖向矩形左边只能是两个横向的矩形,画完之后我们发现,两个横向矩形上面多出来一个空,只能用横向矩形填,填完后,我们发现,现在的结果居然和第一次填图的结果一模一样!好了,至此,对于任意n>2&&n为偶数,因为有两种对称情况,f[n]不能被竖线分割的情况都只有两者,那么对于f[4]的两种情况,我们可以定义为f[0]=1。

递推公式如下:f[n]=f[n]*f[n-2]+2*(f[n-4]+f[n-6]+f[n-8]+....+f[0]);


AC代码如下:

#include<stdio.h>
#include<cstring>
using namespace std;
typedef long long ll;
#define MAX 1003
ll f[MAX];
const int PI=100003;

int main()
{
    int n;
    memset(f,0,sizeof(f));
    f[0]=1;
    f[2]=3;
    for(int i=4;i<=1000;i++)
    {
        f[i]=(f[i-2]*f[2])%PI;
        int t=4;;
        while(t<=i)
        {
            f[i]=(f[i]+2*f[i-t])%PI;
            t+=2;
        }
    }
    while(scanf("%d",&n),n)
    {
        printf("%I64d\n",f[n]);
    }
    return 0;
}

2.汉诺塔问题

问题描述:

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

问题分析:

       汉诺塔问题是特别经典的递归分析问题。我们先举一个例子来进一步理解汉诺塔是如何移动的。另从左到右的三个柱子依次编号为1、2、3,三个盘子依次命名为(1)、(2)、(3),在第一根柱子上放3个黄金圆盘。3个圆盘的时候移动过程如下:

(1)1->3

(2)1->2

  (1)   3->2

(3)1->3

(1)2->1

(2)2->3

(1)1->3

至此完成。

很明显的递归,我们先用递归的思路来考虑问题,要想递归,我们先解决两个问题。

(1)终止条件是什么?

在这里,终止条件即为,一个圆盘的时候,直接移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值