LIS是DP入门的一个基础题了
可以看这个,讲得很清晰
http://www.acmerblog.com/dp-3-longest-increasing-subsequence-4640.html
n^2模板:
/* LIS 的动态规划方式实现*/ /* lis() returns the length of the longest increasing subsequence in arr[] of size n */ int dp[MAXN],v[MAXN]; int n; int lis() { int i, j, ans = 0; /* Initialize LIS values for all indexes */ for ( i = 0; i < n; i++ ) dp[i] = 1; /* Compute optimized LIS values in bottom up manner */ for ( i = 1; i < n; i++ ) for ( j = 0; j < i; j++ ) if ( v[i] > v[j] && dp[i] < dp[j] + 1) { dp[i] = dp[j] + 1; ans = max(ans,dp[i]); } return ans; }
nlogn讲解:
http://www.acmerblog.com/lis-nlogn-4730.html
模板:
int n,top; int stk[MAXN],v[MAXN]; void lis() { top = 0; stk[0] = -1; for(int i=0;i<n;i++) { if(v[i]>stk[top]) { stk[++top] = v[i]; } else { int lo=1,hi=top,mid; while(lo<=hi) { mid = (lo+hi)>>1; if(v[i]>stk[mid]) lo = mid+1; else hi = mid -1; } stk[lo] = v[i]; } } }
此外还可以用lower_bound 函数,这个函数内部也是用二分查找
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int num[10]={3,6,3,2,4,6,7,5,4,3}; const int INF=0x3f3f3f3f; int l=10; int g[100]; int d[100]; int main() { fill(g,g+l,INF); int max_=-1; for(int i=0;i<l;i++) { int j=lower_bound(g,g+l,num[i])-g; d[i]=j+1; if(max_<d[i]) max_=d[i]; g[j]=num[i]; } printf("%d ",max_); return 0; }