题目1
1.1、题目分析
其实本题和最长递增子序列的求解一模一样。可以利用动态规划来快速实现。
为了能够找到可重集中 最大的不连续子集的大小,我们先对原始数据升序,然后dp:
1)dp[i]含义:
表示i之前包括i的最长上升子序列的长度。即下标i对应元素包含在内的不连续子集最大长度;
2)递推公式:
dp[i] = Max(dp[i],dp[j]+1),
在满足条件下(nums[i]>nums[j]+1),位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。注意这里不是要dp[i] 与 dp[j] + 1进行比较,而是我们要取dp[j] + 1的最大值。
3)初始化
每一个i,对应的dp[i](即最长上升子序列)起始大小至少都是1.
4)遍历顺序:
dp[i] 是有0到i-1各个位置的最长升序子序列 推导而来,那么遍历i一定是从前向后遍历。
j其实就是0到i-1,遍历i的循环在外层,遍历j则在内层,代码如下:
for (int i = 1; i < nums.size(); i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]+1) dp[i] = max(dp[i], dp[j] + 1);
}
if (dp[i] > result) result = dp[i]; // 取长的子序列
}
1.2、代码
import java.io.*;
import java.util.*;
class test
{
public static void main (String[] args) throws java.lang.Exception
{
//输入
Scanner sc =new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++){
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
//算法
/*
dp[i] 表示从0~i范围内的最大不连续子集长度
dp[i]=dp[j]+1 表示dp[i]的长度 等前面0到j的各个位置满足条件+1 从中选出最长的作为dp[i]的长度
**/
int [] dp = new int[arr.length];
Arrays.fill(dp,1);//初始化 每一个元素可以看做是长度为1不连续子集长度
int result =0;
for(int i=1;i<dp.length;i++){
for(int j=0;j<i;j++){
if(arr[i]-arr[j]>1){
dp[i]=Math.max(dp[i],dp[j]+1);
}
if(dp[i]>result) result=dp[i];// 维护当前最长的不连续长度
}
}
System.out.println(result);
}
}
-=======================================
题目二
1、题目描述
未完 待续~~~~