“状态转移方程,是动态规划中本阶段的状态往往是上一阶段状态和上一阶段决策的结果。
public int lengthOfLIS(int[] nums) {int dp[] = new int[nums.length];Arrays.fill(dp, 1);for (int i = 0; i < nums.length; i++) {for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}}int res = 0;for (int i = 0; i < dp.length; i++) {res = Math.max(res, dp[i]);}return res;}
// 二分查找int lengthOfLIS(int[] nums) {int[] top = new int[nums.length];// 牌堆数初始化为 0int piles = 0;for (int i = 0; i < nums.length; i++) {// 要处理的扑克牌int poker = nums[i];/***** 搜索左侧边界的二分查找 *****/int left = 0, right = piles;while (left < right) {int mid = (left + right) / 2;if (top[mid] > poker) {right = mid;} else if (top[mid] < poker) {left = mid + 1;} else {right = mid;}}/*********************************/// 没找到合适的牌堆,新建一堆if (left == piles) piles++;// 把这张牌放到牌堆顶top[left] = poker;}// 牌堆数就是 LIS 长度return piles;}
拓展二维 354. 俄罗斯套娃信封问题
public int maxEnvelopes(int[][] envelopes) {Arrays.sort(envelopes, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {return o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0];}});int[] height=new int[envelopes.length];for (int i = 0; i <envelopes.length ; i++) {height[i]=envelopes[i][1];}return lengthOfLIS(height);}public int lengthOfLIS(int[] nums) {int dp[] = new int[nums.length];Arrays.fill(dp, 1);for (int i = 0; i < nums.length; i++) {for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}}int res = 0;for (int i = 0; i < dp.length; i++) {res = Math.max(res, dp[i]);}return res;}
static int binarySearch(int w, int n, int[] wt, int[] val) {
int[][] dp = new int[n + 1][w + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= w; j++) {
if (wt[i - 1] > j) { //由于dp数组i要从1开始,所以w数组要减一,避免数组越界(dp[1]的时候w[0])
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = Math.max(dp[i - 1][j - wt[i - 1]] + val[i - 1], dp[i - 1][j]);
}
}
}
return dp[n][w];
}
public static void main(String[] args) {
int[] wt = {2, 1, 3};
int[] val = {4, 2, 3};
System.out.println(binarySearch(4, 3, wt, val));
}
