给定正整数序列 x 1 … , x n x_1 \ldots, x_n x1…,xn。
令 a 1 , a 2 , … , a s a_1, a_2, \ldots, a_s a1,a2,…,as 为构造 S S S 时所使用的下标, b 1 , b 2 , … , b s b_1, b_2, \ldots, b_s b1,b2,…,bs 为构造 T T T 时所使用的下标。且 ∀ i ∈ [ 1 , s − 1 ] \forall i \in [1,s-1] ∀i∈[1,s−1],都有 a i < a i + 1 a_i \lt a_{i+1} ai<ai+1, b i < b i + 1 b_i \lt b_{i+1} bi<bi+1。则 S S S 和 T T T 不同,当且仅当 ∃ i ∈ [ 1 , s ] \exists i \in [1,s] ∃i∈[1,s],使得 a i ≠ b i a_i \neq b_i ai=bi。
第一行有一个正整数 n n n,表示给定序列的长度。接下来的一行有 n n n 个正整数 x 1 , . . . , x n x_1, ..., x_n x1,...,xn。
4
3 6 2 5
2
2
3
1 ≤ n ≤ 500 1 \le n\le 500 1≤n≤500
最长不下降子序列问题是一个经典的算法问题,可以通过动态规划的方法解决。下面我将详细介绍解决该问题的基本思想和步骤。
最长不下降子序列问题的基本思想是利用动态规划的思想,通过构建一个辅助数组来记录以每个元素结尾的最长不下降子序列的长度。通过遍历整个序列,不断更新辅助数组的值,最终得到最长不下降子序列的长度。
创建一个辅助数组 d p dp dp,长度与原始序列相同,用于记录以每个元素结尾的最长不下降子序列的长度。
初始化辅助数组 d p dp dp的所有元素为 1 1 1,表示每个元素本身就构成一个长度为 1 1 1的不下降子序列。
从第二个元素开始遍历原始序列,对于每个元素 n u m s [ i ] nums[i] nums[i],遍历其前面的所有元素 n u m s [ j ] nums[j] nums[j]( j j j从0到 i i i- 1 1 1)。
在内层循环中,如果nums[ i i i]大于等于nums[ j j j],说明可以将 n u m s [ i ] nums[i] nums[i]加入到以 n u m s [ j ] nums[j] nums[j]结尾的不下降子序列中,此时更新 d p dp dp[ i i i]为 d p dp dp[ j j j]+ 1 1 1。
在每次更新 d p dp dp[ i i i]时,同时更新一个全局变量 m a x x maxx maxx,用于记录最长不下降子序列的长度。
最后返回 m a x x maxx maxx作为结果。
例如,对于序列[ 3 3 3, 4 4 4, 2 2 2, 8 8 8, 5 5 5, 1 1 1],按照上述步骤进行计算:
总结: 最长不下降子序列问题通过动态规划的思想,利用辅助数组记录以每个元素结尾的最长不下降子序列的长度,从而得到最长不下降子序列的长度。这种方法的时间复杂度为 O ( n 2 ) O(n^2) O(n2),其中 n n n是序列的长度。
#include
#define N 1001
typedef long long ll;
using namespace std;
long long k,n,q,m,maxx=-1,a[N],f[N],c[N];
int main() {
cin >>n;
for(int i=1; i<=n; i++)
cin >>a[i];
for(int i=1; i<=n; i++) {
f[i]=1;
for(int j=1; j<i; j++)
if(a[j]<=a[i] && f[j]+1>f[i])
f[i]=f[j]+1;
if(f[i]>maxx) {
maxx=f[i];
k=i;
}
}
printf("%d",maxx);
return 0;
}