576. Out of Boundary Paths(Hard)

原题目:
  There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 109 + 7.

Example 1:
Input:m = 2, n = 2, N = 2, i = 0, j = 0
Output: 6
Explanation:

1

Example 2:
Input:m = 1, n = 3, N = 3, i = 0, j = 1
Output: 12
Explanation:

2
Note:
1.Once you move the ball out of boundary, you cannot move it back.
2.The length and height of the grid is in range [1,50].
3.N is in range [0,50].

题目大意如下:
  给定一个m行n列的一个表格和一个球,球的初始坐标按(i,j)的形式给出,你可以每次向四个方向(上下左右)移动这个球一步,但是最多只能移动N步。要求找到所有把球移出这个表格(出界)的方法的次数。答案特别大所以要mod109 + 7再返回。

解题思路:

  设p[i][j][k]:做第i次移动的时候,横坐标为j,纵坐标为k的位置上“有球”。
  
  过程:
  
  ①初始p[0][x][y]=1(我把初始坐标(i,j)变更为(x,y)防止混淆),表示(x,y)这个位置有球,对于每一个p[i][j][k],考虑p[i-1][j][k](对所有j和所有k),如果p[i-1][j][k]不为0,即上一步(i,j)这个位置“有球”。
  
  ②对于每一个“有球”的位置,考虑四个方向的移动——i+1,i-1,j+1,j-1,如果移动后坐标合法,即没有被移除边界则p[i][new_i][new_k]+=p[i-1][j][k],这是一个优化,因为可能多次移动到同一个地方,反之,如果被移除了边界count+=p[i-1][j][k],这两个公式就是状态转移的过程;
  
  ③最后我们需要的答案就是count。

代码如下:

class Solution {
public:
    int findPaths(int m, int n, int N, int x, int y) {
        int p[N+1][m][n] ;
        int count = 0 ;
        int mod = (int)(1e9+7) ;
        memset(p, 0 , sizeof(p)) ;
        p[0][x][y] = 1 ;
        for(int i = 1 ; i <= N ; ++i){
             for(int j = 0 ; j < m ; ++j){
                for(int k = 0 ; k < n ; ++k){
                    if(p[i-1][j][k] != 0){
                        //cout << "检查到: " <<"p["<<i-1<<"]["<<j<<"]["<<k<<"]="<< p[i-1][j][k] <<endl;

                        if(j+1 < 0 || j+1 >= m) {
                            count +=p[i-1][j][k] ;
                            count %=mod ;
                            //cout <<"p["<<i<<"]["<<j+1<<"]["<<k<<"]"<<" 不合法"<<endl;
                        }
                        else {
                            //cout << "位置: " <<"p["<<i<<"]["<<j+1<<"]["<<k<<"]"<<" 加一"<<endl;
                            p[i][j+1][k]+=p[i-1][j][k] ;
                            p[i][j+1][k]%=mod ;
                        }
                        if(j-1 < 0 || j-1 >= m) {
                            count +=p[i-1][j][k] ;
                            count %=mod ;
                            //cout <<"p["<<i<<"]["<<j-1<<"]["<<k<<"]"<<" 不合法"<<endl;
                        }
                        else {
                            //cout << "位置: " <<"p["<<i<<"]["<<j-1<<"]["<<k<<"]"<<" 加一"<<endl;
                            p[i][j-1][k]+=p[i-1][j][k] ;
                            p[i][j-1][k]%=mod ;
                        }
                        if(k+1 < 0 || k+1 >= n) {
                            count +=p[i-1][j][k] ;
                            count %=mod ;
                            //cout <<"p["<<i<<"]["<<j<<"]["<<k+1<<"]"<<" 不合法"<<endl;
                        }
                        else {
                            //cout << "位置:  " <<"p["<<i<<"]["<<j<<"]["<<k+1<<"]"<<" 加一"<<endl;
                            p[i][j][k+1]+=p[i-1][j][k] ;
                            p[i][j][k+1]%=mod ;
                        }
                        if(k-1 < 0 || k-1 >= n) {
                            count +=p[i-1][j][k] ;
                            count %=mod ;
                            //cout <<"p["<<i<<"]["<<j<<"]["<<k-1<<"]"<<" 不合法"<<endl;
                        }
                        else {
                            //cout << "位置: " <<"p["<<i<<"]["<<j<<"]["<<k-1<<"]"<<" 加一"<<endl;
                            p[i][j][k-1]+=p[i-1][j][k] ;
                            p[i][j][k-1]%=mod ;
                        }
                    }

                }
             }
        }
        return count%mod ;
    }
};

算法分析:
  三个循环,相当于填补一个三维的矩阵,所以复杂度显然为O(n³)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值