/*
* POJ-1716.cpp
*
* Created on: 2013年11月19日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 10010;
struct node{
int x;
int y;
bool operator<(const node& b)const{
return y < b.y;
}
}a[maxn];
bool vis[maxn];
/**
* 本题的题意是:
* 在几个区间中选择几个数,加入到集合中,使得每个区间至少有两个数出现在集合中...
* 求这个集合最小有多少个数
*
* 解题策略:贪心
* 贪心选择旺旺发生在极端选择处,这个思想和POJ1328那道雷达的题目的思想是一样的...
* 先对区间按右端点进行排序。然后从左往右判断该区间中是否已经有2个元素出现在集合中.
* 如果没有选择最右的端点加入到集合..(为什么选择右端点加入到集合而不是选择左端点呢???举一个例子:
* 在(1,3)、(2,5)这两个区间中,很明显选择3加入到集合中能使集合中的元素的个数尽可能的少)
*/
int main(){
int n;
while(scanf("%d",&n)!=EOF){
int i;
for(i = 0 ; i < n ; ++i){
scanf("%d%d",&a[i].x,&a[i].y);
}
memset(vis,false,sizeof(vis));
sort(a,a+n);
int count = 2;
vis[a[0].y] = true;
vis[a[0].y - 1] = true;
int j;
for(i = 1 ; i < n ; ++i){
int m = 0;
for(j = a[i].x ; j <= a[i].y ; ++j){//判断第i个区间赢有多少个数出现在集合中
if(vis[j]){
m++;
}
if(m >= 2){//如果这个区间已经有2个数出现在集合中,则已经满足条件,跳出本层循环
break;
}
}
if(m == 0){//如果这个区间没有数出现在集合中,则选择最后两个数加入到集合中
count += 2;
vis[a[i].y] = true;
vis[a[i].y - 1] = true;
}
if(m == 1){//如果这个区间只有一个数出现在集合中,则选择最后一个数加入到集合中
count += 1;
vis[a[i].y] = true;
}
}
printf("%d\n",count);
}
return 0;
}
(Relax 贪心1.7)POJ 1716 Integer Intervals
原创
©著作权归作者所有:来自51CTO博客作者CAIHONGSHIJIE6的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Integer Intervals (P1716)
这个题的意思是:找出一个数的集合(是离散开的)其中的第在给出的区间中至少存在两点。像
intervals integer go each input -
poj 1716(贪心)
题意:给出数轴上的n个区间,每
贪心 ci 按序 #include -
poj 1201 Intervals 线段树+贪心
nclude #include using namespace st
#include i++ 单点更新 -
【POJ 1716】 Integer Intervals
【题目链接】 点击打开链接 【算法】 差分约束系统 【代码】
#include ios i++ 差分约束系统 学习 -
POJ 1089 Intervals 区间覆盖+ 贪心
来源:http://poj.org/problem?id=1089题意:就是给你一些区间,若两个区间能够合并,则合并。求最后又多少个区间,输出最后的区间。思路:其实就是一个贪心的题目,不过要想做到1A还是有点困难的。有许多情况需要考虑清楚,我也是wa了几次才过的。我们可以先按开始端点从小到大排序,若开始端点相等,则按结尾端点从小到大排序。排序之后能合并则合并。合并的时候有两种情况,一种是起点和开始点的起点一样,但是终点比开始点的终点大,这种情况需要考虑;另一种就是开始点小于等于起点的结束点。在合并的过程中,起点的结尾点需要一直不断的更新。代码:#include <iostream>
#include i++ ios #define 数值 题解 学习笔记 编程语言