思路:
这题明显比前面一提要难得多,关键是跳的级数不确定了。
这题一开始一看我就知道可以从最底下,深搜到顶。(因为牛客对算法复杂度要求不是太高,要是这题在洛谷绝对GG)
深搜模板了解下;
public void dfs(int i, int k) {
if(i>k)return;
if(i==k) {
sum++;
return;
}
for (int j = 1; j <=k; j++) {
i +=j;
if(i<=k)dp(i,k);
i-=j;
}
// 万变不离其宗的模板;
我们来尝试找一下规律
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
F(n) | 1 | 2 | 4 | 8 | 16 | 32 | 64 |
找规律得F(n)=2F(n-1)
这样只能说是硬找的规律,要是硬推要怎么推呢?
F(2)=F(1)+F(0)F(3)=F(0)+F(1)+F(2)F(4)=F(0)+F(1)+F(2)+F(3)F(n−1)=F(0)+F(1)+F(2)+……+F(n−2)F(n)=F(0)+……+F(n−2)+F(n−1)因为F(n−1)=F(0)+F(1)+F(2)+……+F(n−2)所以F(n)=2∗F(n−1);
F
(
2
)
=
F
(
1
)
+
F
(
0
)
F
(
3
)
=
F
(
0
)
+
F
(
1
)
+
F
(
2
)
F
(
4
)
=
F
(
0
)
+
F
(
1
)
+
F
(
2
)
+
F
(
3
)
F
(
n
−
1
)
=
F
(
0
)
+
F
(
1
)
+
F
(
2
)
+
…
…
+
F
(
n
−
2
)
F
(
n
)
=
F
(
0
)
+
…
…
+
F
(
n
−
2
)
+
F
(
n
−
1
)
因
为
F
(
n
−
1
)
=
F
(
0
)
+
F
(
1
)
+
F
(
2
)
+
…
…
+
F
(
n
−
2
)
所
以
F
(
n
)
=
2
∗
F
(
n
−
1
)
;
得出我们的递推式。
其实我们还可以找到一种更简单的规律
F(n)=2(n−1)
F
(
n
)
=
2
(
n
−
1
)
//方法一: 深度优先算法
public int sum =0;
public int JumpFloorII(int target) {
dfs(0,target);
return sum;
}
public void dfs(int i, int k) {
if(i>k)return;
if(i==k) {
sum++;
return;
}
for (int j = 1; j <=k; j++) {
i +=j;
if(i<=k)dp(i,k);
i-=j;
}
}
// 方法二:递推式
public int JumpFloorII(int target) {
if(target<=2)return target;
return 2*JumpFloorII(target-1);
}
//其实这个方法就挺好的了,没有大量重复计算。
// 方法三:找规律,
public int JumpFloorII(int target) {
if(target<=2) return target;
return (int)Math.pow(2, target-1);
// return 1<<(target-1); 两种方法都可以
}
//其实这题还有居多的做法, 比如(记忆化搜索,动态规划,留给大家来思考)