1269. 停在原地的方案数

思路:
对于这个题,除开第一个位置不能从左边过来,和最后一个位置不能从右边过来,其余位置都可以有三种可能。
三种可能分别是,不动,左移,右移。因此我们可以得到状态转移方程。
我们定义dp[step][idx],step为移动次数,idx为当前的位置
首先是第一个位置:dp[i][0] = dp[i-1][0]+dp[i-1][1]; 即原地不动+从右边过来的
最后一个位置:dp[i][maxidx-1] = dp[i-1][maxidx-1]+dp[i-1][maxidx-2];即原地不动+左边过来的
其余位置:dp[i][j] = dp[i-1][j]+dp[i-1][j-1]+dp[i-1][j+1];即原地不动+左边过来的+右边过来的。

因为step可能小于或大于arrlen,所以idx最大值应该为 min(step,arrlen),因为idx最多只能到两者最小的一个的数的位置。

代码:

class Solution {
private:
    const int mod = 1000000007;
public:
    int numWays(int steps, int arrLen) {
        int maxidx = min(steps , arrLen );
        vector<vector<int>> dp(steps+1 , vector<int>(maxidx+1));
        dp[0][0]=1;
        for(int i=1; i<=steps; ++i){
            for(int j=0;j<maxidx;++j){
                dp[i][j] = dp[i-1][j]; //每个位置,固定会有不动的方案
                if(j-1>=0) dp[i][j] = (dp[i][j]+dp[i-1][j-1]) % mod; //这是控制不为第一个位置
                if(j+1<=maxidx) dp[i][j] = (dp[i][j]+dp[i-1][j+1]) % mod; //控制不为最后一个元素
            }
        }
        return dp[steps][0];
    }
};

其实还能想到,右移和左移次数应该相同才能回到位置0,因此step/2才应该用来和arrlen 取 min,但是我写的一直报错堆溢出,没有搞懂。

posted @ 2021-05-13 11:34  Mrsdwang  阅读(38)  评论(0编辑  收藏  举报