蓝桥杯——最长上升子序列(新手方法)

蓝桥杯——最长上升子序列(新手方法)_第1张图片

把问题简单化

1.首先 求最长上升序列包含几个元素   ,new 一个a[] c存序列元素,new 一个dp[] 存当前元素的最长序列(就是以这个元素为结尾的最长上升序列的长度,比如  这里的第6个元素 “1”   以这个元素结尾的最长上升序列为 { -1 0 1}) 需要两次for循环,外层循环 for i   表示要寻找第i个元素结尾的最长上升序列,内层循环代表找前面元素的最长上升序列(如果a[i]小于前面的元素 a[j]就可以接上 dp[j] ,也就是最长上升序列,最终循环比较大小,让i接上最大的d[j] 。最后可以得到最大的d[i]

2.接下来求dp[]对应的元素,就是每 for i 一次d[i][]就更新一次,注意如果      if(dp[i] 

3.本人新手,希望能帮助大家,不足之处肯定很多,望大佬多多指点

public static void main(String[] args) {

       int a [] = new int [1005];

     int dp[] = new int [1005];

     int dpin[][] = new int [1005][1005];

     int n ;

     Scanner scan = new Scanner (System.in);

     n = scan.nextInt();  

     int nn = 0;

     for (int i = 1;i<=n;i++)

       a[i] = scan.nextInt();

     for(int i = 1;i<=n;i++) {

       dp[i] = 1;

       int index  = 0;

       for(int j = 1;j看看此时第i 个元素,可以接到哪些元素后边  最后经过一轮循环,会得出最大值,就是接到哪个元素的后面序列最长

         if(a[j] < a[i]) {       // 出现比前面已经遍历元素小的情况

//          dp[i] = Math.max(dp[i],dp[j]+1);       如果只用求出长度就直接这样写,不用 if 判断

                  if(dp[i]

                    for(int ii = 1;ii<=dp[j];ii++) { // 更新数组,把现在已知最长的序列输入数组

                      dpin[i][ii] = dpin[j][ii];

                    }

                    dpin[i][dp[j]+1] = a[i];// 把自己放到里面

                    dp[i] = dp[j] + 1;// 更新以第i 个元素为尾的最长子序列

                    index = 1;// 完成更新,打标签

                  }

                  else

                    dp[i] = dp[i]; // 可去掉

         }

         }   

       //System.out.printf("dp[%d]=%d\n",i,dp[i]);

       if (index == 0) {

      dpin[i][1] = a[i]; // 没有打过标签,说明以i 结尾的最长上升子序列就是本身,长度为 1

       }

     }

     int max = 0;

     int maxi = 0;

     for(int i =1;i<=n;i++) // 找最大值

       if(max 

         max = dp[i];

         maxi = i;

       }

    

     for(int i = 1;i<=dp[maxi];i++) {  // 按照题目格式输出

       if (i==dp[maxi])

         System.out.println(dpin[maxi][i]); 

       else

       System.out.print(dpin[maxi][i]+" "); 

       }

    }

你可能感兴趣的:(蓝桥杯,算法,职场和发展)