import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		int a[][]=new int[n][2];
		for (int i = 0; i < a.length; i++) {
			a[i][0]=scanner.nextInt();
			a[i][1]=scanner.nextInt();
		}
		Arrays.sort(a,(c,b)->(c[0]-b[0]));//给二维数组根据位置排序
		int v[]=new int[n+1];
		for (int i = 1; i <= n; i++) {
			v[i]=a[i-1][1];//把速度提取出来
		}
		//二分+贪心
		ArrayList<Integer> list=new ArrayList<>();
		list.add(v[1]);
		for (int i = 2; i < v.length; i++) {
			if(v[i]>=list.get(list.size()-1)) {
				list.add(v[i]);//大于等于直接加在后面
			}else {
				//小于就替换第一个大于v[i]的数
				//使用二分
				int l=0;int r=list.size()-1;
				while(l<r) {
					int m=(l+r)/2;
					if(list.get(m)<=v[i]) {
						l=m+1;
					}else {
						r=m;
					}
				}
				//结束以后l索引的值就是第一个大于v[i]的值
				list.set(l, v[i]);//set替换,将指定索引的值用新给的值替换
				
			}
		}
		int len=list.size();
		System.out.println(n-len);
		

	}

}

这里n的取值有10的5次方,不难使用传统的动态规划,会超时,我们应该采用二分+贪心的思路来优化,创建一个集合,来装每一个长度结束时的值,如果v[i]大于等于该值,就直接把该值加到集合后面,反之,我们就采取优化,把第一个大于v[i]的值用v[i]替换掉。