问题:
求一个一维数组中最长递增子序列的长度。
解法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