递推2

第1题     骨牌2

有2×n的一个长方形方格,用一个1×2的骨牌铺满方格。 
例如n=3时,为2×3方格。此时用一个1×2的骨牌铺满方格,共有如下3种铺法: 

微信图片_20220123170110.png


试对给出的任意一个n(0<n<90),求出铺法总数。 

输入/输出例子1

输入:2

输出:2

#include<bits/stdc++.h>
using namespace std;
long long n,a[95];
int main(){
    cin>>n;
    a[1]=1,a[2]=2;
    for(int i=3;i<=n;i++)
    {
        a[i]=a[i-1]+a[i-2];
    }
    cout<<a[n];
    return 0;
}
第2题     铺地砖(floor)(nhoi2012xx4)

一天,晨晨的数学老师布置了一道题目,大意如下:用1*1和2*2的瓷砖不重叠地铺满n*3的地板,共有多少种方案?

例如:

n=1时:1*3的地板方法就一个,直接由三个的瓷砖铺满。

n=2时:2*3的地板可以由下面3种方案铺满:

123.jpg

输入格式

第一行:一个整数n(1<=n<=50)

输出格式

输出铺满n*3的地板的方案数

输入/输出例子1

输入:

3

输出:

5

样例解释

数据范围

对于20%的数据,1<=n<=15;

对于50%的数据,1<=n<=30;

对于100%的数据,1<=n<=50;

#include<bits/stdc++.h>
using namespace std;
long long f[55],n;
int main(){
    cin>>n;
    f[1]=1,f[2]=3;
    for(int i=3;i<=n;i++)
    {
        f[i]=2*f[i-2]+f[i-1];
    }
    cout<<f[n];
    return 0;
}
第3题     蜜蜂路线(简化)

一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:
蜜蜂从蜂房M开始爬到蜂房N,1<=M< N<=50,有多少种爬行路线?

pimg2073_1.jpg

输入格式

输入M,N的值。

输出格式

爬行有多少种路线。

输入/输出例子1

输入:

1 14

输出:

377

#include<bits/stdc++.h>
using namespace std;
long long n,m,a[55];
int main(){
    cin>>m>>n;
    n=n-m+1;
    a[1]=1,a[2]=1;
    for(int i=3;i<=n;i++)
    {
        a[i]=a[i-1]+a[i-2];
    }
    cout<<a[n];
    return 0;
}
第4题     老鼠走迷宫

为了迎接2008年鼠年的到来,老鼠王国举行了盛大的游园活动,其中有一个叫"走迷宫"的活动,老鼠在八边形的蜂状迷宫(如下图)里可以向下、向右、斜向上、斜向下爬行到相邻的蜂房中去,不能反向爬行。当然,蜂房里还有一只猫,有猫的蜂房老鼠是不敢进去的,只能绕过。试求老鼠从蜂房1爬到蜂房N所有可能路线的总数。

1234.jpg

输入格式

共2行,第1行1个整数N(1<=N<=100),表示老鼠要达到的蜂房,第2行1个整数M(M<=N),表示猫在蜂房的位置。

输出格式

一个整数S,表示老鼠从蜂房1爬到蜂房N所有可能路线的总数,如果不能达到,则输出0。答案可能很大。

输入/输出例子1

输入:

4

2

输出:

2

#include<bits/stdc++.h>
using namespace std;
long long f[105],n,m;
int main(){
    cin>>n>>m;
    if(m==1||m==1)
    {
        cout<<0;
        return 0;
    }
    f[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(i==m) continue;
        if(i%2==0) f[i]=f[i-1]+f[i-2]+f[i-3];
        else f[i]=f[i-1]+f[i-2];
    }
    cout<<f[n];
    return 0;
}
第5题     马拦过河卒简化版

棋盘上A点有一个过河卒,需要走到目标点。卒行走的规则:可以向下、或者向右。那么从点(0,0)开始,每次只能向下走一步或者向右走一步,到达点(x,y)有多少种不同的走法?

输入格式

两个整数,即x和y。 0 <= x, y < = 10。

输出格式

一个整数,不同的走法的数量。

输入/输出例子1

输入:

1 1

输出:

2

#include<bits/stdc++.h>
using namespace std;
int a[15][15],n,m;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        a[i][0]=1;
    for(int i=1;i<=m;i++)
        a[0][i]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            a[i][j]=a[i-1][j]+a[i][j-1];
        }
    cout<<a[n][m];
    return 0;
}
第6题     街道路径

设有一个N*M(1<=N<=50,1<=M<=50)的街道,规定行人从A(1,1)出发,在街道上只能向东或北行走。

2065.png

若在此街道中,设置一个矩形障碍区域(包括围住该区域的的街道)不让行人通行,如上图中用“*”表示的部分。此矩形障碍区域用2对顶点坐标给出,如上图中的2对顶点坐标为(2,2),(8,4),此时从A出发到达B的路径有两条。
现给出N、M,同时再给出此街道中的矩形障碍区域的2对顶点坐标(x1,y1),(x2,y2),请求出此时所有从A出发到达B的路径的条数。

输入格式

第一行输入n,m
第二行分别输入对应障碍的定点坐标x1,y1,x2,y2

输出格式

一行,即所有从A出发到达B的路径的条数

输入/输出例子1

输入:

9 5
2 2 8 4

输出:

2

#include<cstdio>
#include<algorithm>
#define maxn 60
#define l 10000000000
using namespace std;
struct number{
 long long d1,d2;
}f[maxn][maxn];
int n,m;
int flag[maxn][maxn];
void start(){
 long long s; 
 f[1][1].d1=1;f[1][1].d2=0;
 for(int k=3;k<=m+n;k++)
 for(int i=1;i<=n;i++){
 if(k-i>=1&&k-i<=m&&!flag[i][k-i]){
 int j=k-i;
 if(j-1>=1) f[i][j]=f[i][j-1];
 if(i-1>=1){
 s=f[i][j].d1+f[i-1][j].d1;
 f[i][j].d1=s%l;
 f[i][j].d2=(f[i-1][j].d2+f[i][j].d2+s/l)%l;
 }
 }
 }
 if(f[n][m].d2==0) printf("%I64d\n",f[n][m].d1);
 else printf("%I64d%010I64d\n",f[n][m].d2,f[n][m].d1);
}
int main(){
 int x1,x2,y1,y2;
 scanf("%d%d",&n,&m);
 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
 if(x1>x2) swap(x1,x2);
 if(y1>y2) swap(y1,y2);
 for(int i=x1;i<=x2;i++)
 for(int j=y1;j<=y2;j++)
 flag[i][j]=1;
 start();
 return 0; 
}
  • 附加题 
  • 第1题     马拦过河卒(noip2002pj4) 

    棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

    1032.png

    棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

    输入格式

    一行四个数据,分别表示B点坐标和马的坐标。

    输出格式

    一个数据,表示所有的路径条数。

    输入/输出例子1

    输入:

    6 6 3 2

    输出:

    17

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,x,y,c=0;
    int s[205][205];
    int dx[9]={0,-2,-1,1,2,2,1,-1,-2};
    int dy[9]={0,1,2,2,1,-1,-2,-2,-1};
    void search(int x,int y){
    	if(x==n&&y==m) c+=1;
    	if(y<=m&&s[x][y+1]==0) search(x,y+1);
    	if(x<=n&&s[x+1][y]==0) search(x+1,y);
    }
    int main(){
    	scanf("%d%d%d%d",&n,&m,&x,&y);
    	s[x][y]=1;
    	for(int i=1;i<=8;i++){
    		int xx=x+dx[i],yy=y+dy[i];
    		if(xx>=0&&xx<=n&&yy>=0&&yy<=m) s[xx][yy]=1;
    	}
    	search(0,0);
    	printf("%d",c);
    	return 0;
    }
    第2题     骑士游历问题(knight) 

    设有一个 n×m 的棋盘(2 ≤ n ≤ 50,2 ≤ m ≤ 50),在棋盘上任一点有一个中国象棋“马”,马走的规则为:马走日字;马只能向右走。当 n,m 给出后,同时给出马起始的位置和终点的位置,试找出从起点到终点所有路径的数目。

    输入格式

    n,m,x1,y1,x2,y2 (分别表示棋盘大小、起点坐标和终点坐标)。

    输出格式

    路径数目(若不存在,则输出0)

    输入/输出例子1

    输入:

    30 30 1 15 5 15
    

    输出:

    8

    #include<bits/stdc++.h>
    using namespace std;
    long long n,m,x, y, xx, yy, a[55][55];
    bool f(int x,int y)
    {
        if(x>=1 && x <= n && y>=1 && y <= m) return 1;
        return 0;
    }
    int main()
    {
    	cin>>n>>m>>x>>y>>xx>>yy;
        swap(n,m);swap(x,y);swap(xx,yy);
        a[x][y]=1;
        for(int j=y+1;j <= yy;j++)
            for(int i=1;i <= n;i++)
            {
                if(f(i-2,j-1)) a[i][j]+=a[i-2][j-1];
                if(f(i-1,j-2)) a[i][j]+=a[i-1][j-2];
                if(f(i+1,j-2)) a[i][j]+=a[i+1][j-2];
                if(f(i+2, j-1)) a[i][j]+=a[i+2][j-1];
            }
        cout <<a[xx][yy];
    	return 0;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值