动态规划思路:(借鉴自《代码随想录》)
- dp数组的含义(一维or二维)
- 递推公式
- 初始化
- 遍历顺序
- 手动模拟
一、基础题
牛客BM62 斐波那契数列
public int Fibonacci(int n) {
if(n == 0 || n == 1) return 1;
if(n < 0 || n > 40) return -1;
int[] dp = new int[n+1];
dp[1] = 1; dp[2] = 1;
for(int i = 2; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}//Fibo
牛客BM63 跳台阶
public int jumpFloor(int target) {
if(target >= 1 && target <= 40){//输入合法
if(target == 1){
return 1;
}else if(target == 2){
return 2;
}else {
int[] dp = new int[target+1];
dp[1] = 1;
dp[2] = 2;
for(int i = 3; i < target+1; i++) {
dp[i] = dp[i-1] + dp[i-2];
}//for
return dp[target];
}
}
return -1;
}//jumpFloor
牛客BM64 最小花费爬楼梯
public int minCostClimbingStairs (int[] cost) {
int n = cost.length;//一共n个台阶
if(n == 1) return 0;
//dp[i]:到第i个台阶的最小花费
int[] dp = new int[n+1];
//从0或1号台阶开始
dp[0] = 0;
dp[1] = 0;
if(n == 2) return 0;
for(int i = 2; i <= n; i++) {//从上一个阶梯来or从上两个阶梯来
dp[i] = Math.min(cost[i-1] + dp[i-1], cost[i-2] + dp[i-2]);
}
return dp[n];
}//minCostClimbingStairs
二、子序列问题
连续子序列
牛客BM72 连续子数组的最大和
public int FindGreatestSumOfSubArray(int[] array) {//连续子数组的最大和
if(array.length == 1) return array[0];
//动态规划
int n = array.length;
int[] dp = new int[n];//dp[i]:以i为结尾为的连续数组的最大和
dp[0] = array[0];
int max = array[0];
for(int i = 1; i < n; i++) {
dp[i] = Math.max(dp[i-1] + array[i], array[i]);
max = Math.max(max, dp[i]);
}//for
return max;
}//fun
回文
牛客BM73 最长回文子串
public int getLongestPalindrome (String A) {
// write code here
int max = 1;
if(isValid(A)) {
//初始化
boolean[][] dp = new boolean [A.length()][A.length()];默认为false
//遍历
for(int i = A.length()-1; i>= 0; i--) {
for(int j = i; j < A.length(); j++) {
if(i == j) {//自己和自己回文
dp[i][j] = true;
max = Math.max(max, j-i+1);
}else if(j -i == 1){//长度为2相等回文
if(A.charAt(i) == A.charAt(j)) {
dp[i][j] = true;
max = Math.max(max, j-i+1);
}
}else {//长度>=3
if(A.charAt(i) == A.charAt(j)) {//
if(dp[i+1][j-1]) {
dp[i][j] = true;
max = Math.max(max, j-i+1);
}
}
}//if-else if-if
}//for-j
}//for-i
}//if-valid
return max;
}//getLongestPalindrome
public static boolean isValid(String str) {
if(str.length() >= 0 && str.length() <= 1000 && str.matches("[A-Za-z0-9]*")) {
return true;
}
return false;
}//isValid