• 最长上升子序列


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

    方法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 }



  • 相关阅读:
    k8镜像
    幂等设计
    复杂思考,简单设计。 https://mp.weixin.qq.com/s/xmkFzEpzIauJgus3MMmkaQ
    GDP Streaming RPC 设计
    The zero value for a Mutex is an unlocked mutex. 零值
    reflect.DeepEqual 反射 比较值相等
    Go 和 C 的变量定义异同 nil 值判断 汇编
    https://www.luogu.com.cn/blog/wangrx/finitecalculus
    HTML a标签链接 设置点击下载文件 react 路由 静态路由 动态路由 虚拟路由
    Mars 微信跨平台跨业务基础组件
  • 原文地址:https://www.cnblogs.com/chenbin7/p/2203092.html
Copyright © 2020-2023  润新知