采用lower_bound
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int n,num[100100],lis[100100],len;
while(scanf("%d",&n)!=EOF)
{
len = 0;
memset(lis,0,sizeof(lis));
for(int i=0;i<n;i++)//如果i是从1开始,在lower_bound中的到的位置会返回到0,这样就不可以把lis[1]的位置替换掉,从而WA。
{
scanf("%d",&num[i]);
}
lis[0] = num[0];
for(int i=1;i<n;i++)
{
if(num[i] > lis[len])//如果num比lis[len]选择的终点大,则可以放入lis,即新的终点。
lis[++len] = num[i];
else
{
int pos = lower_bound(lis,lis+len,num[i]) - lis;//注意lower_bound 的用法,lower_bound返回的是一个地址
lis[pos] = num[i];//!!!
}
}
printf("%d\n",len+1);//len是从0开始的,所以要加上1。
}
}
这里lis相当于dp数组,lis[i]记录到长度为i的上升子序列的末尾元素最小是多少
int dp[max];
int a[max];
void solve()
{
int res=0;
for(int i=0;i<n;i++)
{
dp[i]=1;
for(j=0;j<i;j++)
{
if(a[j]<a[i])
dp[i]=max(dp[j]+1,dp[i]);
}
res=max(res,dp[i]);
}
printf("%d",res);
}
这里的dp数组记录的是到某一位最长上升子序列的长度,比较好想,只要找这一位前面的比他小的就可以了
最大上升自序列和(由最长上升自序列改进)
#include<bits/stdc++.h>
using namespace std;
int a[1005];
int dp[1005];
int main()
{
int n;
while(scanf("%d",&n),n)
{
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int j;
int res=0;
for(i=0;i<n;i++)
{
dp[i]=a[i];
for(j=0;j<i;j++)
if(a[j]<a[i])
dp[i]=max(dp[i],dp[j]+a[i]);
if(dp[i]>res)
res=dp[i];
}
printf("%d\n",res);
}
}