最简单题目之最长递增子序列
思路框架:
1. 定义状态
明确问题的最优子结构和状态转移方程
定义dp数组,以及如何迭代dp
2. 明确状态转移
如何迭代dp
3. 初始化边界条件
4. 从边界条件进行迭代计算
5. 提取结果
解析
1. 定义状态
目的是找到最长上升子序列,设置dp为第index个的最长最优子序列,
即知道dp[0..i-1],就可以推导出dp[i]
2. 明确状态转移
dp[i]为 当num[i]>num[k]时,dp[k] + 1, 前i-1个比第i个值小的num的dp最大子序列+1 的最大值就是第i个dp最长的最优子序列
逻辑:
func findLenOfLIS(arr []int) int {
dp:=make([]int, len(arr)) // init with 1 所有值
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
if (arr[i] > arr[j])
dp[i] = Math.max(dp[i], dp[j] + 1)
}
}
// dp转移可以优化, 最近的一定最大
for (int i = 0; i < arr.length; i++) {
for (int j = i-1; j >= 0; j--) {
if (arr[i] > arr[j])
dp[i] = Math.max(dp[i], dp[j] + 1)
continue
}
}
int res = 0; for (int i = 0; i < dp.length; i++) { res = Math.max(res, dp[i]); } return res;
}
dp stands for Dynamic Programming