每日一题LeetCode 403 青蛙过河 dp 哈希

https://leetcode-cn.com/problems/frog-jump/

思路

f [ i ] [ j ] f[i][j] f[i][j]在第 i i i个格子处能否跳距离 j j j,以0/1表示,那么

f [ i ] [ j ] = f [ k ] [ j − 1 ] ∣ ∣ f [ k ] [ j ] ∣ ∣ f [ k ] [ j + 1 ] , k 为上个点的位置 f[i][j] = f[k][j-1] \quad || \quad f[k][j]\quad|| \quad f[k][j+1] ,\qquad k \text{为上个点的位置} f[i][j]=f[k][j1]f[k][j]f[k][j+1],k为上个点的位置

k可以取为

k = { i − ( j − 1 ) 对应石子 i − j 对应石子 i − ( j + 1 ) 对应石子 k=\begin{cases} i-(j-1) \text{对应石子}\\ i-j\text{对应石子}\\ i-(j+1)\text{对应石子} \end{cases} k=i(j1)对应石子ij对应石子i(j+1)对应石子

要快速的根据石头坐标找到位置,可以用一个哈希表映射。

const int maxn = 2005;
class Solution {
     
    public:
    int f[maxn][maxn];
    vector<int> p;
    unordered_map <int,int> hash;
    int dp(int i,int j)
    {
     
        if(f[i][j] != -1)
            return f[i][j];
        f[i][j] = 0;
        for(int k = max(1,j - 1);k <= j + 1;k++){
     
            int x = p[i] - k;
            if(hash.count(x)){
     
                x = hash[x];
                if(dp(x,k)){
     
                    f[i][j] = 1;
                    break;
                }
            }
        }
        return f[i][j];
    }
    bool canCross(vector<int>& stones) {
     
        p = stones;
        for(int i =0;i < stones.size();i++)
            hash[stones[i]] = i;
        memset(f,-1,sizeof(f));
        f[0][1] = 1;
        for(int i = 0;i <= stones.size() ; i++){
     
            if(dp(stones.size() - 1,i))
                return true;
        }
        return false;
    }
};

你可能感兴趣的:(LeetCode,动态规划)