zoukankan      html  css  js  c++  java
  • 面试基础算法题

    动态规划求数组中最长的上升序列(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;
          }    
    }
  • 相关阅读:
    IOI 1996 网络协议
    lougu P2344奶牛抗议
    Poj3764 The XOR-longest Path
    A Simple Problem with Integers (线段树)
    NOIP2011 选择客栈
    20181029 T3 乐谱分段
    20181029 T2 寻宝游戏
    20181029 T1 教科书般的亵渎
    NOIP2011聪明的质监员
    浅谈AC自动机
  • 原文地址:https://www.cnblogs.com/mrdblog/p/7513984.html
Copyright © 2011-2022 走看看