拿着这份代码也可以通过此题,但是这份代码有一个错误的逻辑点,就是二分那里关于边界缩小的决策有问题
可以发现 if (dp[mid] <= arr[i])不管是取小于还是小于等于都可以通过此题,但是小于才是正确的逻辑
#include <iostream>
using namespace std;
int n;
int arr[100005], dp[100005];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> arr[i];
}
int ans = 1;
dp[1] = arr[1];
for (int i = 2; i <= n; i++)
{
if (arr[i] > dp[ans])//如果可以加进来
{
dp[++ans] = arr[i];
}
else
{
int l = 1, r = ans;
while (l < r)
{
int mid = (l + r) >> 1;
if (dp[mid] <= arr[i])
//这里的决策是:如果arr[i]更大或者相等,那么就缩小左边界,
//如果相等时做了此决策,那么会导致arr[i]优化了另一个数,称其为a,这样a便会与dp[mid]相等,违背了严格递增的条件
{
l = mid + 1;
}
else
{
r = mid;
}
}
dp[l] = arr[i];
}
}
cout << n - ans;
}
//附上样例,会发现if那里取小于,小于等于,结果并不相同
30
89 126 85 103 101 86 86 98 96 99 89 81 101 92 79 77 82 97 83 100 78 72 79 97 71 80 98 89 69 74