玄关:学了半天,一回头看二分还是不懂QAQ
  • 板块学术版
  • 楼主Star_Sky_
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/9/20 20:55
  • 上次更新2024/9/20 21:35:57
查看原帖
玄关:学了半天,一回头看二分还是不懂QAQ
1046223
Star_Sky_楼主2024/9/20 20:55

在做P1439的时候炸的……

一开始,我一直是这么写的(导弹拦截的时候这么写也没问题):

#include <iostream>
#include <cstdio>

using namespace std;

int n, l, r, mid, cnt, ans;
int p1[100005], p2[100005], mp[100005], dp[100005]={1145140};

int main(){
	scanf("%d", &n);
	for(int i=1; i<=n; i++)scanf("%d", &p1[i]), mp[p1[i]]=i;
	for(int i=1; i<=n; i++)scanf("%d", &p2[i]), p2[i]=mp[p2[i]];
	
	for(int i=1; i<=n; i++){
		l=0, r=n;
		while(l<=r){
			mid=(l+r)/2;
			
			if(dp[mid]>=p2[i]){
				cnt=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		
		ans=max(ans,cnt+1);
		dp[cnt+1]=p2[i];
	}
	
	printf("%d", ans+1);
	return 0;
}

核心的寻找上升序列部分在导弹拦截并没有错,但不知道为什么在这题只有20pts?

机房大佬改成了这样:

#include <iostream>
#include <cstdio>

using namespace std;

int n, l, r, mid, cnt, ans;
int p1[100005], p2[100005], mp[100005], dp[100005];

int main(){
	scanf("%d", &n);
	for(int i=1; i<=n; i++)scanf("%d", &p1[i]), mp[p1[i]]=i;
	for(int i=1; i<=n; i++)scanf("%d", &p2[i]), p2[i]=mp[p2[i]];
	dp[0] = 1145141919;
	for(int i=1; i<=n; i++){
		l=0, r = ans + 1;
		while(l<r - 1){
			mid=(l+r)/2;
			
			if(dp[mid]<p2[i]){
				cnt=mid;
				l=mid;
			}
			else r=mid;
		}
		
		ans=max(ans,l+1);
		dp[l+1]=p2[i];
	}
	
	printf("%d", ans);
	return 0;
}

大佬说是二分左闭右闭的问题,但我没看出来这有什么区别,玄关!!!

QwQ

2024/9/20 20:55
加载中...