POJ 2376(优先队列 + 一维DP)

/*
	这个题可以用DP做:
		用优先队列(对左边数值排序) ;
			第一个区域:先初始化:这个区域的值为 1; 
			第二步:DP
				假设要求(i,j) 这个区域的;
				那么DP公式是:
					DP(x)  = DP[i-1] + 1; (i<= x <=j);
*/ 

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int N,T;
int L[1000005];
typedef struct area{
	int l,r;
	area(int a, int b){
		l = a;
		r = b;
	}
	area(){
	}
	
	//在队列中,这一个区域包括另一个区域,要取 这个区域;(1, 3); (1, 10);
	// 要(1,10)要在队列前面;这样一来,(1, 3)就可以直接PASS;
	// 这是很大程度上提高的程序运行速度; 
	friend bool operator < (area a, area b){
		if(a.l == b.l){
			return a.r < b.r;
		}
        return a.l>b.l; 
    }
} Area;
priority_queue<area> que;
int main(){
//	freopen("a.txt", "r", stdin);
//	freopen("b.txt", "w", stdout);	
	int a,b;
	Area temp;
	while(~scanf("%d%d", &N, &T)){
			while(!que.empty()) que.pop();
			for(int i=0; i<=T; ++i){
				L[i] = 0;
			}
			for(int i=1; i<=N; ++i){
				scanf("%d %d", &a, &b);
				que.push(area(a, b));
			}
			
			//第一步开始  功能:初始化第一个区域的值; 
			temp = que.top(); que.pop();
			if(temp.l != 1){
				printf("-1\n");
				continue;
			}
			for(int i=temp.l; i<=temp.r; ++i){
				L[i] = 1;
			}
			int end = temp.r;
			//第一步结束 
			//第二步开始 这一步开始DP; 
			while(!que.empty()){
				temp = que.top();
				que.pop();
				if(temp.r <= end){
					continue;
				}
				for(int i=temp.l; i<=temp.r; ++i){
					if(L[i] != 0){
						continue;
					}
					if(L[temp.l - 1] != 0)
						L[i] = L[temp.l - 1] + 1;
				}
				end = temp.r;
			}
			//第三步结束
			
			//第四步输出结果 
			if(L[T] == 0){
				printf("-1\n");
				continue;
			}
			printf("%d\n", L[T]);
	}
	return  0;
}

发布了76 篇原创文章 · 获赞 0 · 访问量 7193

猜你喜欢

转载自blog.csdn.net/julicliy/article/details/79576095