数组最长递增子序列

这个问题和矩阵相乘比较相似,但因为它只需要计算A[1...j]的代价,因此比矩阵相乘少了一层循环,矩阵相称的复杂度是n的3次方,这个问题的复杂度是n平方的。要把数据打印出来,破费了一点周折,需要好好理解,其中递归退出的条件是,数组记录的位置和自身的位置相同,但这个位置的数据也要输出,因此在else语句中输出最前面的哪个数据,同时最后一个数据需要保存在临时变量,压入栈中,待递归返回时输出数据,整个编写思路模拟矩阵相乘的思路。程序如下:

// LIS[1,j] = max{LIS[1,k] + 1, 1}
#include <stdio.h>
#include <vector>
#include <boost/scoped_ptr.hpp>
void Print(int value) {
  printf("%d ", value);
}
 
template<typename T, typename VisitFun>
void PrintSubarray(const std::vector<T>& array, const size_t* array_offset, size_t position, VisitFun visit_fun) {
  if (position != array_offset[position]) {
    size_t to_print = position;
    PrintSubarray(array, array_offset, array_offset[position], visit_fun);
    visit_fun(array[to_print]);
  } else {
    visit_fun(array[position]);
  }
}
template<typename T>
void LongestIncreaseSubarray(const std::vector<T>& array) {
  size_t max = 0;
  size_t max_position = 0;
  boost::scoped_ptr<size_t> max_length_buffer(new size_t[array.size()]);
  size_t* max_length = max_length_buffer.get();
  boost::scoped_ptr<size_t> array_offset_buffer(new size_t[array.size()]);
  size_t* array_offset = array_offset_buffer.get();
  for (size_t length = 1; length <= array.size(); ++length) {
    max_length[length - 1] = 1;
    array_offset[length -1] = length - 1;
    for (size_t k = 0; k < length; ++k) {
      if (array[k] < array[length - 1] && max_length[k] + 1 > max_length[length - 1]) {
          max_length[length - 1] = max_length[k] + 1;
          array_offset[length - 1] = k;
          if (max_length[length - 1] > max) {
            max = max_length[length - 1];
            max_position = length -1;
            printf("%zd\n", max_position);
          }
      }
    }
    printf("--%zd\n", max_length[length - 1]);      
  }
  for (int i = 0; i < array.size(); ++i) {
    printf("%zd ", array_offset[i]);
  }
  printf("\n");
  PrintSubarray(array, array_offset, max_position, Print);
}
int main(int argc, char** argv) {
  int array_buffer[] = {1, 0, 1,4,5,2,6,1,7,2,8};
  std::vector<int> array(array_buffer, array_buffer + sizeof(array_buffer) / sizeof(int));
  LongestIncreaseSubarray(array);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值