http://www.rqnoj.cn/Problem_167.html
一、思路
x1,x2...xn
其中的xi,xi+1...xj 为最长下降子序列
那么x1...xj+1的最长下降子序列 和xi,xi+1一样
f[i] 记录 包含a[i]的最长下降子序列的长度,那么
f[i] = max(f[k] +1 )其中k>=1 && k<i && a[i]<f[k]
即1-i-1里面最长的满足a[i]<f[k]的f[k]
这样从1--n 一重循环
1--i-1 二重循环
时间复杂度n2
-----------
还要考虑的细节 是 0 不算进去
这样可以70个得分点,其余三个超时
===================
后来改f[k] 为记录最长下降子序列长度为i时的最大值
如果f[k] >a[i]
f[++k] = a[i]
否则
在f[k]中找到其中小于a[i]最大的f[j]值
f[j] = a[i] k 长度不变,即最大下降子序列的长度不变
利用二分查找 logN
时间复杂度nLogN
原本是说a[i]为0的不算进去,结果误写成这个了
导致一个错误点
for (i=1; i<=n&&a[i]; i++)
后面改为了
for (i=1; i<=n; i++)
if (!a[i])
{
continue;
}
AC了
#include <iostream.h>
int a[100001];
int f[100001];
int BinarySearch(int l, int r, int key)
{
if (l <= r)
{
int mid = (l + r) / 2;
if (f[mid] > key)
{
return BinarySearch(mid+1, r, key);
}
else
{
return BinarySearch(l, mid-1, key);
}
}
else
{
return l;
}
}
int main()
{
int i, j, n;
int k = 0;
//int max = -1;
cin>>n;
for (i=1; i<=n; i++)
{
cin>>a[i];
}
f[0] = 999999;
k = 0;
for (i=1; i<=n; i++)
{
if (!a[i])
{
continue;
}
if (f[k]>a[i])
{
f[++k] = a[i];
}
else
{
j = BinarySearch(0, k, a[i]);
f[j] = a[i];
}
}
//cout<<BinarySearch(1, n, 5);
cout<<k;
/*
f[1] = a[1] ? 1 : 0;
for (i=2; i<=n; i++)
{
max = 0;
for (j=1; j<i; j++)
{
if (j<i && a[j]>a[i] && a[i] && max<f[j])
{
max=f[j];
}
}
if (a[i])
{
f[i] = max + 1;
}
}
max = 0;
for (i=1; i<=n; i++)
{
if (max<f[i])
{
max = f[i];
}
}
cout<<max;*/
return 0;
}