1.爬楼梯
- 转移方程:
f(x)=f(x−1)+f(x−2)
- 边界条件:
f(0) = 1,f(1) = 1
public int climbStairs(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2;i < n + 1; i++) {
dp[i] = dp[i-2] + dp[i-1];
}
return dp[n];
}
2.买卖股票的最佳时机
121.买卖股票的最佳时机
f(x) = max(f(x-1), price[x] - minprice)
public int maxProfit(int[] prices) {
if (prices == null || prices.length ==0) {
return 0;
}
int maxp = Integer.MIN_VALUE;
int minp = prices[0];
for (int i = 0; i < prices.length; i++) {
maxp = Math.max(maxp, prices[i] - minp);
minp = Math.min(minp, prices[i]);
}
return maxp;
}
3.买卖股票的最佳时机 II
public int maxProfit(int[] prices) {
// int len = prices.length;
// int[][] dp = new int[len][2];
// dp[0][0] = 0;
// dp[0][1] = -prices[0];
// for (int i = 1; i < len; i++) {
// dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
// dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
// }
// return dp[len - 1][0];
int res = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
res += prices[i] - prices[i-1];
}
}
return res;
}
4.最大子序和
public int maxSubArray(int[] nums) {
if (nums.length == 0) {
return 0;
}
int maxSum = nums[0];
for (int i = 1; i < nums.length; i++) {
if(nums[i - 1] > 0) {
nums[i] += nums[i - 1];
}
maxSum = Math.max(maxSum, nums[i]);
}
return maxSum;
// int maxSum = nums[0], sum = nums[0];
// for (int i = 1; i < nums.length; i++) {
// sum = Math.max(sum + nums[i], nums[i]);
// maxSum = Math.max(maxSum, sum);
// }
// return maxSum;
// 暴力法
// if (nums == null || nums.length == 0) {
// return 0;
// }
// int maxSum = Integer.MIN_VALUE;
// for (int i = 0; i < nums.length; i++) {
// int sum = 0;
// for (int j = i; j < nums.length; j++) {
// sum += nums[j];
// maxSum = Math.max(maxSum, sum);
// }
// }
// return maxSum;
}
5.打家劫舍
public int rob(int[] nums) {
if (nums.length == 0) {
return 0;
}
int N = nums.length;
int[] dp = new int[N + 1];
dp[0] = 0;
dp[1] = nums[0];
for (int i = 2; i <= N; i++) {
dp[i] = Math.max(dp[i - 1], nums[i - 1] + dp[i - 2]);
}
return dp[N];
// if (nums == null || nums.length == 0) {
// return 0;
// }
// if(nums.length == 1) {
// return nums[0];
// }
// int len = nums.length;
// int[] dp = new int[len];
// dp[0] = nums[0];
// dp[1] = Math.max(nums[0],nums[1]);
// int maxSum = 0;
// for (int i = 2; i < nums.length; i++) {
// dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
// }
// return dp[len - 1];
}
6.打家劫舍Ⅱ
public int rob(int[] nums) {
int l = nums.length;
if (l == 0) {
return 0;
}
if (l ==1) {
return nums[0];
}
int[] dp1 = new int[l];
int[] dp2 = new int[l];
dp1[0] = 0;
dp1[1] = nums[0];
dp2[0] = 0;
dp2[1] = nums[1];
for (int i = 2; i < l; i++) {
dp1[i] = Math.max(dp1[i - 1], dp1[i - 2] + nums[i - 1]);
}
for (int i = 2; i < l; i++) {
dp2[i] = Math.max(dp2[i - 1], dp2[i - 2] + nums[i]);
}
return Math.max(dp1[l - 1], dp2[l - 1]);
}
优化了一下:
public int rob(int[] nums) {
int l = nums.length;
if (l == 0) {
return 0;
}
if (l ==1) {
return nums[0];
}
return Math.max(dp(nums, 0, l - 1), dp(nums, 1, l));
}
private int dp(int[] nums, int start, int end) {
int pre = 0, cur = 0, tmp;
for (int i = start; i < end; i++) {
tmp = cur;
cur = Math.max(cur, pre + nums[i]);
pre = tmp;
}
return cur;
}
7.礼物的最大价值
public int maxValue(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
}
return dp[m][n];
}