20240125-边界外路径

文章介绍了一个涉及动态规划的编程问题,解决小球在给定网格中通过指定步数移动到边界的不同路径数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目要求

有一个m*n的网格,网格中有一个小球。小球初始位置位[startRow,startColumn]。您可以将小球移动到网格中相邻的四个单元格之一(可能会越过网格边界移出网格)。最多可以对小球进行maxMove移动。

给定 m、n、maxMove、startRow、startColumn 这五个整数,返回将小球移出网格边界的路径数。由于答案可能非常大,因此请返回 10^9+7的模数。

Example 1:

 

Input: m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0
Output: 6

Example 2:

 

Input: m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1
Output: 12

思路

这个题目有三个状态:横坐标、纵坐标和可移动的次数,所以我们可以用一个三维的dp数组存储这三个状态或者一个带有三个参数的dp函数。

状态转移关系:在maxMove步之内从(i,j)位置踢出界外的路径数量等于在maxMove-1步之内从(i,j)的相邻位置踢出界外的路径数量之和。(相邻位置多走一步可以到达i,j)

注意处理计算的冗余和基础情况。这里的递归采用的是数组和递归函数相结合的方式。参考labuladong的思路和题解。

代码

class Solution {
public:
    int memo[50][50][51];
    int m, n;

    int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
        this->m = m;
        this->n = n;
        memset(memo, -1, sizeof(memo));
        return dp(maxMove, startRow, startColumn);
    }

    int dp(int maxMove, int i, int j) {
        // base case,找到一条出界路径
        if (i < 0 || j < 0 || i >= m || j >= n) {
            return 1;
        }
        // 避免冗余计算
        if (memo[i][j][maxMove] != -1) {
            return memo[i][j][maxMove];
        }
        // 无法在有限的步数内出界
        if (maxMove == 0) {
            return 0;
        }
        // 状态转移关系:
        // 在maxMove步之内从(i,j)踢出界外的路径数量等于
        // 在maxMove-1步之内从(i,j)的相邻位置出界的路径数量之和;
        long res = 0;
        res += dp(maxMove - 1, i-1, j);
        res += dp(maxMove - 1, i+1, j);
        res += dp(maxMove - 1, i, j-1);
        res += dp(maxMove - 1, i, j+1);
        memo[i][j][maxMove] = (int)(res % 1000000007);
        return memo[i][j][maxMove];
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值