题在?64页
Solution
优化前:从后面往前找就完了
优化后:找到每个长度对应最小的末尾数,最后取末尾数最大(同时保证该数为相同长度LIS的最小末尾数)的一个的长度。真是妙啊
补充一下关于二分:
*lower_bound(a,a+n,k)寻找>=k的第一个a[n]
lower_bound(a,a+n,k)-a寻找>=k的的一个n
可能是正确的 照着写的一定没问题的代码
优化前
#include<iostream>
#include<cstdio>
using namespace std;
int a[1001],dp[1001];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i)
{
dp[i]=1;
for(int j=1;j<i;++j)
{
if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+1);
}
}
printf("%d\n",dp[n]);
return 0;
}
优化后:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=1000001;
int main()
{
int n;
int dp[1001],a[1001];
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
fill(dp+1,dp+1+n,inf);
for(int i=1;i<=n;++i)
{
*lower_bound(dp+1,dp+1+n,a[i])=a[i];
}
printf("%d\n",lower_bound(dp+1,dp+1+n,inf)-dp-1);
return 0;
}