区间DP概述(JAVA)
区间DP
- 概述
- 例题
- 例题一 更小的数
- 例题二 能量项链
概述
区间DP和线性DP其实从代码角度来说就是遍历处理的顺序不一样
合并:即将两个或多个部分进行整合,也可以反过来;
特征:能将问题分解为能两两合并的形式;
求解:对整个问题设最优值,枚举合并点,将问题分解为左右两个部分,最后合并两个部分的最优值得到原问题的最优值。
例题
例题一 更小的数
这个题典型的用区间DP,可以看到比大小如果首位和末位的大小确定,是否满足条件就可以确定,而大小相等的时候就需要用到前面已经得到的dp[i+1][j-1]
package com.js.datastructure.recursion.蓝桥.国特训练营.动态规划线性DP;import java.util.Scanner;public class 更小的数 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);//字符串长度为n//由数字0~9组成//选取子串并且把子串翻转//dp[i][j] 代表下标从i到j子串的个数String s = scanner.nextLine();int len = s.length();int t = s.length();boolean[][] dp = new boolean[len][len];int ans = 0;for (int i = 2; i <= t; i++) {//代表子串的长度for (int j = 0; j < len - i + 1; j++) {int k = j + i - 1;if(s.charAt(j) > s.charAt(j + i - 1)){dp[j][k] = true;ans++;} else if (s.charAt(j) < s.charAt(j + i - 1)) {dp[j][k] = false;}else {dp[j][k] = dp[j+1][k-1];if(dp[j][k]){ans++;}}}}System.out.println(ans);}
}
例题二 能量项链
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {//需要把v[]再复制一份(使得每个数的遍历都是数组长度)//例如:输入 1 2 3 4 复制成 1 2 3 4 1 2 3 4//状态转移方程 dp[i][j] = Math.max(dp[i][k]+dp[k+1][j]+sum(i,k,j)) (i<=k<j)Scanner scan = new Scanner(System.in);int n = scan.nextInt();int[] arr = new int[2*n+2];for(int i=1;i<=n;i++){arr[i] = scan.nextInt();arr[n+i] = arr[i];}long[][] dp = new long[2*n+2][2*n+2];for(int len=2;len<=n;len++){for(int i=1;i+len-1<=2*n;i++){int j=i+len-1;for(int k=i;k<j;k++){dp[i][j] = Math.max(dp[i][j],dp[i][k]+dp[k+1][j]+arr[i]*arr[j+1]*arr[k+1]);}}}long ans = 0;for(int i=1;i<=n;i++){ans = Math.max(ans,dp[i][i+n-1]);}System.out.println(ans);scan.close();}
}片