为什么提交时候第一问需要减1,但是样例就不用
查看原帖
为什么提交时候第一问需要减1,但是样例就不用
606375
ZAOYIU楼主2023/10/5 01:30

检查过没有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;

}
2023/10/5 01:30
加载中...