一个序列有N个数:A[1],A[2],A[3]……A[N],求最长非降子序列的长度。
最重要的是要找出所谓的“状态”,本题目中是d[i],初始化最长长度为自己本身即一个单位长度。
看是否要加入第i个元素,如果第i个元素a[i]比当前序列的最后一个元素a[j]大的话,那么加入,同时d[i]=d[j]+1;体会d[j]+1>d[i]
,比如,对于序列【5,3,4,8,6,7】当i=3,即a[i]=8的时候,j=0,8比5大,d[3]=d[0]+1=2;j=1,8比3大,但是d[1]+1=2不比d[3]大就不能加一;j=2,8>4,d[2]+1=3>d[3],所以d[3]=d[2]+1;len保存的是前i个元素中的最大非降子序列的长度。
怎么能好好体会其中的思想而不去死记硬背,勉强自己去接受这一想法呢!
#include <iostream>
using namespace std;
int lis(int
a[],int n){
int
d[n];
int len=1;
for(int i=0;i<n;i++){
d[i]=1;
for(int j=0;j<i;j++){
if(a[j]<=a[i]&&d[j]+1>d[i]){
d[i]=d[j]+1;
}
if(d[i]>len)len=d[i];
}
}
return
len;
}
int main()
{
int a[]={5,3,4,8,6,7};
cout<<lis(a,6)<<endl;
return 0;
}
LIS拓展
Problem Statement for ZigZag | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This problem statement is the exclusive and |
来源: <http://community.topcoder.com/stat?c=problem_statement&pm=1259>
#include<stdio.h>
#include<iostream>
using namespace std;
#define LEN 100
int
a[LEN];
int d[LEN];
int
lis(int n){
if(n==1){return 0;}
int len=0;
for(int i=0;i<n;i++){
d[i]=1;
}
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
if(j>0&&i>0&&(a[j-1]-a[i-1])*(a[j]-a[i])<0 && d[j]+1 >d[i])
d[i]=d[j]+1;
if(len<d[i])len=d[i];
}
}
return len;
}
int main(){
int n;
freopen("in.txt","r",stdin);
while(cin>>n){
for(int i=0;i<n;i++)
cin>>a[i];
cout<<lis(n)+1<<endl;
}
return 0;
}