美文网首页
* 最长不下降子序列

* 最长不下降子序列

作者: 小幸运Q | 来源:发表于2018-07-10 15:08 被阅读22次

image.png
int MAX[N]={0};
// 记录到该点的最长子序列长度
int son[N]={0};
// 记录该点的最长子序列的上一个点的位置

for(i=0;i<counts;i++){
    MAX[i]=1;
    // 所有点i的子序列都大于等于1
}

//  处理MAX数组
  for(i=1;i<counts;i++){
    // 从1开始,因为0不用遍历
    for(j=0;j<i;j++){
      // 从0开始,但是在i-1的时候止步
      if(a[i]>a[j]){
        if(MAX[j]+1>MAX[i]){
          son[i]=j;
          // 记录上一个节点的位置
          MAX[i]=MAX[j]+1;
        }
      }
    }
  }

记录子序列的值对应的数组下标(只记录其中一个):

void print(){
  int i,j;
  int output[N]={0};
  for(i=counts-1;i>=0;i--){
    int start=0;
    int next=son[i];
    output[start]=i;
    while(next!=son[next]){
      output[++start]=next;
      next=son[next];
    }
    output[++start]=next;
    // 最后一个节点不要忘了
    if(start==largest-1){
      // start长度值小1
      for(j=0;j<largest;j++){
        cout<<output[j]<<"-->";
      }
      cout<<endl;
    }
  }
}

#include <bits/stdc++.h>
using namespace std;
#define N 10000
int points,edges;
int MAX[N]={0};
// 以该节点为端点的不下降子序列的最大长度
int num[N]={0};
// 存放输入
int son[N]={0};
// 存放上一级节点
vector<int>v;
int findstart(int end,int maxlength){
  int i,j;
  int start=end;
  cout<<num[end]<<">>";
  while(start>=0){
    // 当start==son[start],说明到达了子串的起点,break
    if(start!=son[start]){
      start=son[start];
      cout<<num[start]<<">>";
    }
    else{
      break;
    }
  }
  cout<<endl;
  return start;
}
int main(){
  int i=0,j,input,length=0;
  scanf("%d",&length);
  for(i=0;i<length;i++){
    scanf("%d",&input);
    num[i]=input;
    MAX[i]=1;
    son[i]=i;
  }
  length=i;

  MAX[0]=1;
  // 以i为子序列的终点,遍历所有num比它小的MAX
  // 得到max(MAX[i],MAX[j]+1)作为MAX[i]的最终值
  for(i=1;i<length;i++) {
    for(j=0;j<i;j++){
      if(num[j]<num[i]){
        if(MAX[i]<MAX[j]+1){
          // j更适合加入串
          MAX[i]=MAX[j]+1;
          // 记录串中上一个节点的坐标
          son[i]=j;
        }
      }
    }
  }

  // 从MAX[i]中找出最长子串的长度
  int maxlength=0;
  int end=-1;
  int start=0;
  for(i=0;i<length;i++){
    if(MAX[i]>maxlength){
      maxlength=MAX[i];
      end=i;
    }
  }

  cout<<"maxlength:"<<maxlength<<endl;
  cout<<"end:"<<end+1<<endl;
  // 利用end和maxlength沿着son[]一路补全整个串
  start=findstart(end,maxlength);
  cout<<"start:"<<start+1<<endl;
}


/*
10
1 3 5 4 2 3 6 4 2 7
*/

相关文章

  • 子序列问题

    最长公共子序列 最长上升/下降/不升/不降子序列

  • 机试常用算法和题型-动态规划专题

    动态规划专题 最大连续子序列求和 方法二:很巧妙 最大加权子矩阵-矩阵压缩 最长不下降子序列 最长不下降子序列应用...

  • [基础DP][CF580A]Kefa and First Ste

    题目大意 求最长的连续不下降子序列。 题目分析 设f[x]表示以x这个位置结尾的最长不下降子序列的长度,那么f[x...

  • * 最长不下降子序列

    记录子序列的值对应的数组下标(只记录其中一个):

  • DP经典问题代码

    斐波那契数列 (动态规划的递归写法) 数塔问题 (动态规划的递推写法) 最大连续子序列和 最长不下降子序列 最长公...

  • 公共子序列问题

    最长公共子序列 最长上升子序列 最长公共上升子序列

  • 最长递增子序列: 动态规划和LCS(最长公共子序列)

    最长递增子序列: 动态规划和LCS(最长公共子序列)子序列和子串的区别:子序列不连续,字串连续。这个题两种解法 动...

  • dp经典问题

    1. 最长子序列问题 最长上升不连续子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入:...

  • 动态规划设计

    1. 最长子序列问题 最长上升不连续子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入:...

  • 算法(04)动态规划

    零钱问题 背包问题 最长公共子序列 最长公共子串 最长上升子序列 最大连续子序列和

网友评论

      本文标题:* 最长不下降子序列

      本文链接:https://www.haomeiwen.com/subject/uasfpftx.html