问题:
求一个一维数组中最长递增子序列的长度。
解法1:
很明显用动态规划的算法,选取下面的阶段(这种选法极为常见),可使阶段间的关系具有无后效性。
阶段:在所有以元素k结尾的子数组中,选出其中的最长递增子序列,k=1,2...n。
状态:以元素k结尾的最长递增子序列中只有一个最长的递增子序列。
#include<iostream> #include<cstring> #include<algorithm> #define MAX 1000 using namespace std; int dp[MAX]; int LIS1(int Array[],int n) { int i,j; int max=-0xFFFFFFF; for(i=1;i<=n;i++) { dp[i]=1; for(j=1;j<i;j++) { if(Array[i]>Array[j]&&dp[j]+1>dp[i]) dp[i]=dp[j]+1; } if(dp[i]>max) max=dp[i]; } return max; } int MinValue(int Array[],int n) { int min=0xFFFFFFF; for(int i=1;i<=n;i++) if(min>Array[i]) min=Array[i]; return min; } int LIS2(int Array[],int n) { int MaxV[MAX];//记录数组中的递增序列信息 MaxV[0]=MinValue(Array,n)-1;//边界值,数组中的最小值 MaxV[1]=Array[1];//边界值,数组中的第一个值 for(int i=1;i<=n;i++)//初始化最长递增序列的信息 dp[i]=1; int nMaxLIS=1;//数组最长递增子序列的初始值 for(int i=1;i<=n;i++) { //遍历历史最长递增序列的信息 int j; for(j=nMaxLIS;j>=0;j--) { if(Array[i]>MaxV[j]) { dp[i]=j+1; break; } } //如果当前最长序列大于最长递增序列长度,更新最长信息 if(dp[i]>nMaxLIS) { nMaxLIS=dp[i]; MaxV[dp[i]]=Array[i]; } else if(MaxV[j]<Array[i]&&Array[i]<MaxV[j+1]) MaxV[j+1]=Array[i]; } return nMaxLIS; } int main(int argc,char *argv[]) { int Array[MAX]; int i,n; cout<<"Please input n= "; cin>>n; cout<<"Please input Array values:"<<endl; for(i=1;i<=n;i++) cin>>Array[i]; cout<<"LIS1: "<<LIS1(Array,n)<<endl; memset(dp,0,sizeof(dp)); cout<<"LIS2: "<<LIS2(Array,n)<<endl; return 0; }
原文地址:http://blog.csdn.net/cstopcoder/article/details/26889623