刚开始做这题的时候,以为是简单的动态规划,后来提交之后发现超时了,看到了N可以达到100000,用简单的动态规划,时间复杂度达到了N^2,明显会超时。
想了挺久的,还是不知道怎么做,百度了一下,才知道了原来运用二分搜索,把问题简化成类似排序,时间复杂度为logN,就不会超时了。
下面是AC的代码,看注释可以很容易理解的。如说的有错,欢迎指正。
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; int a[100005], dp[100005]; int binarysearch(int num, int len) //二分搜索,搜索a数组每个数应该放在dp数组的哪个位置,将位置返回 { //普通的二分搜索,很容易理解的 int left, right, mid; left = 1; right = len; mid = (left + right) / 2; while(left <= right) { if(dp[mid] == num) //该数num在递增序列的中间的情况 return mid; else if(dp[mid] > num) right = mid - 1; else left = mid + 1; mid = (left + right) / 2; } return left; //插到数组dp的最后,也就是递增序列的最后,递增序列加1 } int main() { int n, i, j; while(cin >> n) { for(i = 0; i < n; i++) { scanf("%d", &a[i]); } memset(dp, 0, sizeof(dp)); int len = 1; dp[1] = a[0]; //先放一个数进dp数组 for(i = 1; i < n; i++) //将剩下的a数组中的数一个一个的找到相应的位置 { j = binarysearch(a[i], len); //返回相应的位置 dp[j] = a[i]; //将a【i】赋值过去 if(j > len) //如果该位置j比len大,赋值给len len = j; } cout << len << endl; } return 0; }
时间: 2024-10-29 19:11:13