检查过没有n+1项,难道是二分有问题吗?
代码如下:
#include<iostream>
#include<vector>
using namespace std;
int h[100001];
int dp[100001];
int f[100001];
int dp2[100001];
int f2[100001];
int main() {
int n = 1;
while (cin>>h[n]) {
if (getchar() == '\n')
break;
n++;
}
for (int i = 1; i <= n; i++) {
//cout << h[i]<<" ";
dp[i] = 1;
f[i] = 0;
dp2[i] = 1;
f2[i] = 50001;
}
dp[0] = 1;
f[0] = 50001;
dp2[0] = 1;
f2[0] = 50001;
//求链长度
int result_1 = 1;
f[1] = h[1];
for (int i = 2; i <= n; i++) {
//O(n^2)做法:遍历
//dp[i] = 1;
//for (int j = 1; j < i; j++) {
// if (h[j] >= h[i]) {
// dp[i] = max(dp[i], dp[j] + 1);
// }
//}
//cout << dp[i] << endl;
//O(log n)做法:二分
int left = 0;
int right = result_1 + 1;
int mid = left + (right - left) / 2;
while (right - left > 1) {
mid = left + (right - left) / 2;
if (h[i] <= f[mid]) {
left = mid;
}
else
{
right = mid;
}
}
dp[i] = left + 1;
f[left + 1] = max(f[left + 1], h[i]);
result_1 = max(result_1, dp[i]);
}
//求最长反链长度
int result_2 = 1;
f2[1] = h[1];
for (int i = 2; i <= n; i++) {
//O(log n)做法:二分
int left = 0;
int right = result_2 + 1;
int mid = left + (right - left) / 2;
while (right - left > 1) {
mid = left + (right - left) / 2;
if (h[i] > f2[mid]) {
left = mid;
}
else
{
right = mid;
}
}
dp2[i] = left + 1;
f2[left + 1] = min(f2[left + 1], h[i]);
result_2 = max(result_2, dp2[i]);
}
cout << result_1 - 1<< endl;
cout << result_2 << endl;
}