力扣:1269停留在原地的方案数目

 

感觉应该是dp, 但是一开始只能想到递归处理。

class Solution {
public:
    int ans = 0;

    void dfs(int steps, int direction, int arrLen){
        if(steps == 0)
        {
            if(direction == 0)
                ans++;
            else
                return;
        }
        else
        {
            if(arrLen > 1 + direction)
                dfs(steps - 1, direction + 1, arrLen);
            if(0 <= direction - 1)
                dfs(steps - 1, direction - 1, arrLen);
            dfs(steps - 1, direction, arrLen);
        }
    }

    int numWays(int steps, int arrLen) {
        dfs(steps, 0, arrLen);
        return ans;
    }
};

递归的思路很简单,但是有一个细节就是arrlen是从0开始的,所以最大长度是arrlen - 1. 递归简单,但是容易超时,回忆到以前的知识点“从递归到动态规划”, 两个可变参数说明dp的数组应该是一个二维表来描述状态,

 

class Solution {
public:

    const int mod = 1e9+7;

    int numWays(int steps, int arrLen) {
        int ans = 0;

        //steps对于arrLen是有一定的制约作用的, 有可能简短dp的更新时间的
        arrLen = min(steps, arrLen);
        vector>dp(steps + 1, vector(arrLen, 0));

        //dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] + dp[i][j + 1]
        //要注意边界问题,两个边界都是两部分组成
        //层次结构是自上而下的

        dp[0][0] = 1;
        for (int i = 1; i <= steps; ++i) {
            for (int j = 0; j < arrLen; ++j) {
                for (int k = -1; k <= 1; ++k) {
                    //这一步很有技巧,边界控制的贼稳
                    if (j - k >= 0 && j - k < arrLen) {
                        dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % mod;
                    }
                }
            }
        }
        for(int i = 0; i < steps + 1; ++i)
        {
            for(int j = 0; j < arrLen; ++j)
            {
                cout << dp[i][j] << " ";
            }
            cout << endl;
        }
        return dp[steps][0];
    }
};

// steps = 4, arrLen = 2 时候,申请的数组应该是5行2列

 

你可能感兴趣的:(LeetCode)