l例如:对于[3,1,4,2,5],最长上升子序列的长度是3 arr = [3,1,4,5,9,2,6,5,0] def lis(arr): #dp[i]表示第i个位置的值为尾的数组的最长递增子序列的长度 #初始化数组,假定数组中每个值的最长子序列就是它自己,即都是1 dp = [1 for _ in range(len(arr))] #遍历数组 for i in range(len(arr)): #当遍历到第i个位置时,再依次从0开始遍历到 for j in range(i): #如果第i个位
最长递增子序列是动态规划中最经典的问题之一,我们从讨论这个问题开始,循序渐进的了解动态规划的相关知识要点. 在一个已知的序列 {a1, a 2,...an}中,取出若干数组成新的序列{ai1, ai 2,...aim},其中下标 i1.i2…im保持递增,即新数列中的各个数之间依旧保持原数列中的先后顺序,那么我们称新的序列{ai1, ai 2,...aim}为原序列的一个子序列.若在子序列中,当下标 ix > iy时,aix > aiy,那么我们称这个子序列为原序列的一个递增子序列.最长递增子
题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(dp[k])+1,(k<i),(a[k]<a[i]) #include <stdio.h> #define MAX 1005 int a[MAX];///存数据 int dp[MAX];///dp[i]表示以a[i]为结尾的最长递增子序列(LIS)的长度 int main() { int
最长上升子序列LIS问题属于动态规划的初级问题,用纯动态规划的方法来求解的时间复杂度是O(n^2).但是如果加上二叉搜索的方法,那么时间复杂度可以降到nlog(n). 具体分析参考:http://blog.chinaunix.net/uid-26548237-id-3757779.html 代码: #include <iostream> using namespace std; int LIS_nlogn(int *arr, int len) { int *LIS = new int[len
二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound()的主要区别在于前者返回第一个大于目标值的位置 int lowerBound(int x){ int l=1,r=n; while(l<=r){ int mid=(l+r)>>1; if (x>g[mid]) l=mid+1; else r=mid-1; } return l; } in
//最长上升子序列 #include<iostream> #include<cstring> using namespace std; const int maxn = 10100; int a[maxn],dp[maxn]; int n,k; //a[] 保存原始数据 //dp[i] 表示原始数中以i结尾的上升子序列的长度 int res() { dp[0] = 1; int max = 0; for(int i = 1;i<n;i++) for(int j = 0;j&l