zoj 2136 Longest Ordered Subsequence 最长上升子序
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2136
经典DP,划分为这样的子问题: 记录 length【k】为,以ak为最后一个元素的最长上升子序的长度,那么求这个值时,只需要取出这个数之前的比它小的数,看它的length是多少,取出有最大的length那个。
m记录的是之前子问题的length,初始化为0。
这样实现的结果就是,有length【0】就可以求出length【1】,接着可以求出length【2】......。这样暴力是 O(2^n)的问题(所有的子集都拿出来考察)就变成O(n^2)了
最后的结果是所有length中最小的那个。
#include<iostream> using namespace std; int main() { int size; cin>>size; for(int l=0;l<size;l++) { int n; cin>>n; int *p=new int[n]; int *length=new int[n]; for(int i=0;i<n;i++) cin>>p[i]; length[0]=1; for(int i=1;i<n;i++) { int m=0; //代表之前的个数 length[i]=1; for(int j=0;j<i;j++) { if(p[j]<p[i]) { if(length[j]>m) { length[i]=length[j]+1; m=length[j]; } } } } int max=1; for(int i=0;i<n;i++) if(length[i]>max) max=length[i]; cout<<max<<endl; if(l<size-1) cout<<endl; } }