zoukankan      html  css  js  c++  java
  • 最长上升子序列

    纠结了一晚上,总算理解了。。。欣慰~~

    方法1
     1 /*
    2 动态规划求解思路分析:O(n^2)
    3
    4 经典的O(n^2)的动态规划算法,设arr[i]表示序列中的第i个数,dp[i]表示从1到i这一段中以i结尾的最长上升子序列的长度,
    5 初始时设dp[i] = 0(i = 1, 2, ...,len(arr))。则有动态规划方程:dp[i] = max{1,dp[j]+1} (j=1, 2, ..., i-1, 且arr[j]<arr[i])。
    6
    7 */
    8 #include <iostream>
    9 using namespace std;
    10 int arr[1000];
    11 int dp[1000];
    12
    13 int LIS(int n)
    14 {
    15 int i,j,ans; //ans用于保存最终的最长上升子序列的值
    16 for(i=0;i<n;++i)
    17 dp[i] = 0;
    18
    19 dp[0] = 1;
    20 for(i=1;i<n;++i) //i从第2个元素开始
    21 {
    22 ans = dp[i];
    23 for(j=0;j<i;++j) //遍历从第1个元素到第i-1个元素
    24 {
    25 //当满足 当前元素的值大于前面元素,并且ans小于前面相应元素的dp值时,为ans重新赋值
    26 if( arr[i]>arr[j] && dp[j]>ans )
    27 ans = dp[j];
    28 }
    29 dp[j] = ans+1;
    30 }
    31 ans = 0;
    32 for(i=0;i<n;++i)
    33 {
    34 if(dp[i]>ans)
    35 ans = dp[i];
    36 }
    37 return ans;
    38 }
    39
    40 int main()
    41 {
    42 int n;
    43 while(cin>>n)
    44 {
    45 for(int i=0;i<n;++i)
    46 cin>>arr[i];
    47 cout<<LIS(n)<<endl;
    48 }
    49 return 0;
    50 }

    这个花了好长时间......

    方法2
     1 /*
    2 时间复杂度O(nlogn)
    3 别人总结的(觉得很赞),我按自己的理解,做了修改:
    4 贪心+二分查找:O(nlogn)
    5 开辟一个数组b,类似栈的功能,每次取数组尾元素b[k]和读到的元素arr[i]做比较:
    6 1.1 如果arr[i]>b[k],则赋值给b[k+1];
    7 1.2 如果arr[i]<b[k],则二分查找栈中的比a大的最小的数,并替换。
    8 2.最后序列长度为k的值。
    9 这也是很好理解的,对x和y,如果x<y且E[y]<E[x],用E[x]替换E[y],此时的最长序列长度没有改变但序列Q的''潜力''增大。
    10 举例:原序列为1,5,8,3,6,7
    11 栈为1,5,8,此时读到3,则用3替换5,得到栈中元素为1,3,8, 再读6,用6替换8,得到1,3,6,再读7,得到最终栈为1,3,6,7,最长递增子序列为长度4。
    12
    13 */
    14 #include <iostream>
    15 using namespace std;
    16
    17 int arr[1000];
    18 int b[1000];
    19
    20 int binSearch(int data,int k)
    21 {
    22 int low = 0,high = k;
    23 while(low<=high)
    24 {
    25 int mid = (low+high)/2;
    26 if(data>=arr[mid])
    27 low = mid+1;
    28 else
    29 high = mid-1;
    30 }
    31 return low;
    32 }
    33
    34 int LIS(int n)
    35 {
    36 int k = 0;
    37 b[0] = arr[0];
    38 for(int i=1;i<n;++i)
    39 {
    40 if(arr[i]>=b[k])
    41 {
    42 b[++k] = arr[i];
    43 }
    44 else
    45 {
    46 int pos = binSearch(arr[i],k);
    47 b[pos] = arr[i];
    48 }
    49 }
    50 return k+1;
    51 }
    52
    53 int main()
    54 {
    55 int n;
    56 while(cin>>n)
    57 {
    58 for(int i=0;i<n;++i)
    59 cin>>arr[i];
    60 cout<<LIS(n)<<endl;
    61 }
    62 return 0;
    63 }



  • 相关阅读:
    [Swift]LeetCode241. 为运算表达式设计优先级 | Different Ways to Add Parentheses
    [Swift]LeetCode240. 搜索二维矩阵 II | Search a 2D Matrix II
    使用ADO.NET对SQL Server数据库进行訪问
    JavaScript中面向对象那点事
    总结文件操作函数(二)-C语言
    UVa
    深入研究java.lang.Object类
    TCP/IP具体解释--TCP/IP可靠的原理 滑动窗体 拥塞窗体
    W5500EVB UDP模式的測试与理解
    仿新浪首页、主题、详情页,纯html静态页面
  • 原文地址:https://www.cnblogs.com/chenbin7/p/2203092.html
Copyright © 2011-2022 走看看