动态规划求数组中最长的上升序列(LongestIncreasingSubsequence)的个数,复杂度为O(n^2)。
例如:数组int arr[] = {7,3,5,9,4,6,8,10},最长上升序列应该为3,5,6,8,10或3,4,6,8,10 ,最终答案应该为5;
dp[i]表示数组中以下标i结尾的最长上升序列的个数,则原问题就转换为了求所有dp[i](0<=i<len)中的最大值;
而每一个dp[i]又是以下标i结尾的所有序列中最长上升序列的个数。
import java.util.Scanner;
public class Main
{
public static void main(String[] args) throws Exception
{
Scanner sc = new Scanner(System.in);
while(sc.hasNext())
{
int n = sc.nextInt();
int[] arr = new int[n];
for(int i= 0;i<n;i++)
{
arr[i] = sc.nextInt();
}
System.out.println(maxLIS(arr));
}
}
public static int maxLIS(int[] arr)
{
int max = 1;
int len = arr.length;
int[] dp = new int[len];
dp[0] = 1;
for(int i=1;i<len;i++)
{
for(int j =0;j<i;j++)
{
if(arr[i]>arr[j])
dp[i] = Math.max(dp[i],dp[j]+1);
}
max = Math.max(dp[i],max);
}
return max;
}
}
2.动态规划求连续子数组最大和。
package ers; import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); while(sc.hasNext()) { int n = sc.nextInt(); int[] arr = new int[n]; for(int i= 0;i<n;i++) { arr[i] = sc.nextInt(); } System.out.println(maxLIS(arr)); } } public static int maxLIS(int[] arr) { int len = arr.length; int[] dp = new int[len]; //动态规划记录 dp[0] = arr[0];//初始为第一个数 int start = 0, end = 0; //记录最大子数组的起始位置(在数组中的下标) int MaxSumSub; //最大子数组的值 MaxSumSub = dp[0]; //最大值初始为第一个数 int temp = 0; // for(int i = 1; i < len; i++) { if(dp[i - 1] <= 0) //前面的<0,直接丢弃 { dp[i] = arr[i]; temp = i; //记录起始为止 } else dp[i] = arr[i] + dp[i - 1]; //往后求和 if(dp[i] > MaxSumSub) //找到到i为止的最大子数组 { MaxSumSub = dp[i]; //最大... start = temp; //标记起始 end = i; //标记此时的结束位置 } } for(int j =start;j<=end;j++) System.out.print(arr[j]+" "); System.out.println(); return MaxSumSub; } }