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][j−1]∣∣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−(j−1)对应石子i−j对应石子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;
}
};