蓝桥杯第十一届:走方格--暴搜+动态规划+记忆化搜索

文章展示了三种不同的编程算法来解决从左上角到右下角遍历只有奇数坐标格子的问题,包括暴力搜索(DFS)、动态规划和记忆化搜索。动态规划和记忆化搜索通过优化避免了重复计算,提高了效率。
摘要由CSDN通过智能技术生成

暴搜代码:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
int n, m, cnt;
const int N = 1e3 + 1;
int dx[2] = {1, 0}, dy[2] = {0, 1};
void dfs (int x, int y)
{
    if (x == n && y == m) {
        cnt ++;
        return;
    }
    for (int i=0; i < 2; i ++)
    {
        int a = x + dx[i], b = y + dy[i];
        if (a>n || b>m || (a%2==0 && b%2==0)) continue;
        dfs (a, b);
    }
}

int main()
{
    cin >> n >> m;
    if (n%2==0 && m%2==0){
        cnt = 0;
    }
    else dfs (1, 1);
    
    cout << cnt << endl;
    return 0;
}

动态规划:
下图是:动态规划打表图,很明显可以看出其中每个格子的方案数等于上面格子的方案数 + 左边格子的方案数。
在这里插入图片描述

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 40;
int f[N][N];    //f[i][j]表示从(1,1)走到(i,j)的方案数!
int n, m;
//思考:(i,j)这个点只能由(i-1, j) 或者 (i,j-1)这个点转移过来
// f[i][j] = f[i-1][j]; f[i][j] = f[i][j-1]; 即为转化的可能性!

int main()
{
    cin >> n >> m;
    
    //初始化所有边界的问题!
    for (int i=1; i <= n; i ++)
        f[i][1] = 1;
    for (int j=1; j <= m; j ++)
        f[1][j] = 1;
    
    for (int i=2; i <= n; i ++)
        for (int j=2; j <= m; j ++)
            if (i&1 || j&1)
                f[i][j] = f[i-1][j] + f[i][j-1];
    cout << f[n][m] << endl;
    return 0;
}

记忆化搜索:
从第一个格子开始搜索!
凡是搜索过的格子就给它标注一下,然后下次再遇到这个格子的时候,说明这个格子之前已经走过了,无论它是否走得到终点,它之前走的时候,答案都均已被记录下来了。再走一遍也是同样的效果,没有实际意义!
回溯时标记更新!!!
在这里插入图片描述

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 40;
int f[N][N];    //f[i][j]:表示该点是否已经走过了!
int n, m;
int dfs (int x, int y)
{
    if (x&1 || y&1)
    {
        if (f[x][y]) return f[x][y];
        if (x < n) f[x][y] += dfs (x+1, y);
        if (y < m) f[x][y] += dfs (x, y+1);
    }
    
    return f[x][y];
}

int main()
{
    cin >> n >> m;
    f[n][m] = n&1 || m&1;
    cout << dfs (1, 1);
    return 0;
}```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值