标签:static int rgs oid stat 最大连续子序列 pre 状压 最大
众所周知,DP(dynamic Programming)是在没有特定的套路,刚学的真的摸不着头脑(对,没错就是我)
所以记录一下DP的学习过程(我枯了,大佬快救救孩子吧)
对于一串数A={a_1,a_2,a_3…a_n}A=a1,a2,a3…an,它的子序列为S={s_1,s_2,s_3…s_n}S=s1,s2,s3…s**n,满足 {s_1 < s_2 < s_3 < … < s_m}s1<s2<s3<…<s_m 。求AA*的最长子序列的长度。
第一行是一个整数n(1<=n<=1000)n(1<=n<=1000)。
第二行是nn个数,每个数之间以一个空格隔开。每个数的范围均在int型范围内。
输出
输出最长上升子序列的长度。
样例
5
3 5 4 2 1
2
提示
【数据规模】
100%100%的数据,满足1≤n≤1000。
> ? 1、状态定义
>
> ? dp[i] 表示从下标0到i的上升子序列的最长
>
> ? 2、状态初始化
>
> ? 所有dp[i] = 1; //因为每一个dp[i]最少都自己呀
>
> ? 3、状态转移方程
>
> ? 两层for循环哈
>
> ? dp[i] = Math.max(dp[i],dp[j]+1);
>
> ? 下面来个例子。
>
> ? 10
> ? 9126 1150 1359 3408 2125 2299 4309 5500 3270 2666
> ? 第一次选择 { 9126} dp[0] =1;
> ? 第二次选择了{9126},或者{1150} dp[1] = 1;
> ? 第三次选择{1150,1259} dp[2] = dp[1] + 1;
> ? 第四次选择{1150,1359,3408} dp[3] = dp[2]+1;
> ? 第五次选择{1150,1359,2125} dp[4] = dp[2]+1;
> ? 第六次选择{1150,1359,2125,2299} dp[5] = dp[4]+1;
> ? 每i次选择都是遍历i前面是否存在递增序列的.
> ? 时间复杂度是O(n^2)
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/*
10
9126 1150 1359 3408 2125 2299 4309 5500 3270 2666
第一次选择 { 9126} dp[0] =1;
第二次选择了{9126},或者{1150} dp[1] = 1;
第三次选择{1150,1259} dp[2] = dp[1] + 1;
第四次选择{1150,1359,3408} dp[3] = dp[2]+1;
第五次选择{1150,1359,2125} dp[4] = dp[2]+1;
第六次选择{1150,1359,2125,2299} dp[5] = dp[4]+1;
每i次选择都是遍历i前面是否存在递增序列的.
时间复杂度是O(n^2)
*/
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int[] arr = new int[n];
int[] dp = new int[n];
for(int i =0;i<n;i++){
arr[i] = cin.nextInt();
dp[i] = 1;
}
for(int i =0;i<n;i++){
for(int j =0;j<i;j++){
if(arr[j] < arr[i]){ //前面是单调递增的关系
dp[i] = Math.max(dp[i],dp[j]+1); //要么是自己本来的已经获取到的值,要不然就是当前选择的最大值
}
}
}
// System.out.println(Arrays.toString(dp));
int sum = 0;
for(int i =0;i<n;i++){
if(sum <dp[i]){
sum = dp[i];
}
}
System.out.println(sum);
cin.close();
}
}
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
public class Main {
//这是DP入门的最大连续子序列的最大和
//做DP的话,要明白1、状态定义 2、初始状态 3、状态转移方程(最重要的)
//1、状态定义 :dp[i]:以nums[i]结尾的最大和
//2、初始状态: dp[0] = nums[0]
//3、状态转移方程 dp[i]=Max{num[i],num[i]+dp[i-1]}
public static int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
//首先要对其进行状态初始化
dp[0] = nums[0];
int sum = dp[0];
for(int i =0;i < nums.length;i++){
dp[i] = Math.max(nums[i],dp[i-1] +nums[i]);
if(sum <dp[i]){
sum= dp[i];
}
}
return sum;
}
public static void main(String[] args) {
int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; //结果是6
System.out.println(maxSubArray(nums));
}
}
标签:static int rgs oid stat 最大连续子序列 pre 状压 最大
原文地址:https://www.cnblogs.com/jwthong/p/13279161.html