题目:
HJ103 Redraiment的走法
题解:
dfs 暴力搜索
- 枚举数组元素,作为起点
- 如果后续节点大于当前节点,继续向后搜索
- 记录每个起点的结果,求出最大值
public int getLongestSub(int[] arr) {
int max = 0;
for (int i = 0; i < arr.length; i++) {
int number = dfsForGetLongestSub(arr, i);
max = Math.max(max, number);
}
return max;
}
public int dfsForGetLongestSub(int[] arr, int start) {
if (start > arr.length) {
return 0;
}
int max = 1;
for (int i = start+1; i < arr.length; i++) {
if (arr[i] > arr[start]) {
max = Math.max(max, dfsForGetLongestSub(arr, i) + 1);
}
}
return max;
}
时间复杂度:O()
动态规划
求取最长递增子序列。
设dp[i]表示以i为终点能走的最大步数,当 j < i 时:
- 如果arr[j] < arr[i] 证明可以从 j 跳到 i ,那么dp[i] = dp[j] + 1
- 如果arr[j] >= arr[i] 证明无法从 j 跳到 i ,那么dp[i] = dp[i]
由此可得dp方程,dp[i] = max(dp[i], dp[j]+1)。
dp方程初始化:如果不能调到任何的桩,那么只能在起点,所以初始化 dp[1-n] = 1。
public int getLongestSub(int[] arr) {
int[] dp = new int[arr.length];
int max = 0;
Arrays.fill(dp, 1);
for (int i = 1; i < arr.length; i++)
for (int j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
max = Math.max(max, dp[i]);
}
}
return max;
}
时间复杂度:O()