动态规划问题类型二(求方案数)
动态规划类型一:背包系列问题
最长上升子序列
给定一个长度为 N
的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数N
。
第二行包含 N
个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤10001≤N≤1000,
−109≤数列中的数≤109−109≤数列中的数≤109
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
题解
/**
* @see 动态规划模板 https://www.acwing.com/problem/content/897/
*/
import java.util.Scanner;
public class lengthOfLISClassIO {
static int N = 1010;
static int[] arr = new int[N];
static int[] dp = new int[N];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//这里从数组第二个数开始读入,也可以从第一个开始读入,因为状态转移方程没有涉及到i-1;
for (int i = 1; i <= n; i++) {
arr[i] = sc.nextInt();
}
//集合: 所有以i结尾的上升子序列的长度
//属性:长度的最大值
//集合的划分:以第i-1的数的状态来分类
//即 倒数第二个数是哪个数
//所有以j结尾的上升子序列的长度是dp[j]+1
for (int i = 1; i <= n; i++) {
dp[i] = 1;//最坏情况只有arr[i]一个数
//遍历所有arr[i]之前的数,所以是j < i
for (int j = 1; j < i; j++) {
if (arr[j]<arr[i])
dp[i] = Math.max(dp[i], dp[j]+1);
}
}
int res = 0;
for (int i=1;i<=n;i++){
res = Math.max(res,dp[i]);
}
System.out.println(res);
}
}
函数版
/**
* @see 动态规划模板 https://leetcode-cn.com/problems/longest-increasing-subsequence/
*/
public class lengthOfLISClass {
public static int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
dp[0] = 1;
int res = 1;
for (int i = 1; i < n; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i]>nums[j]){
dp[i] = Math.max(dp[i],dp[j]+1);
}
}
res = Math.max(res,dp[i]);
}
return res;
}
public static void main(String[] args) {
int[] arr = {6};
System.out.println(lengthOfLIS(arr));
}
}