【POJ1716】Integer Intervals——差分约束||贪心

题目大意:给出n个区间,现在要你找出一个点集,使得这n个区间都至少有2个元素在这个点集里面,问这个点集最少有几个点。

解法一:差分约束系统

分析:其实这道题应该说是POJ1201的简化版,不过要注意的一点是,如果你用的是SPFA,那么你的差分约束系统应该为:

          s[b+1]-s[a]>=2;

          s[b+1]-s[b]>=0;

          s[b]-s[b+1]>=1.

为什么下标要全部加上1呢?因为这里的a和b有可能为0,如果按照原来s[a-1]的写法会出现是s[-1]这类数组越界的问题。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn=1e4+5,inf=0x3f3f3f3f;
using namespace std;
struct point{
    int next,w,to;
}e[maxn*3];
int s,t,tot=0,first[maxn],minn=inf,maxx=0,q[maxn];
int dis[maxn];
bool vis[maxn];
int read()
{
    int ans=0,f=1;char c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+c-48;c=getchar();}
    return ans*f;
}
void add(int u,int v,int wi)
{
    tot++;e[tot].next=first[u];first[u]=tot;e[tot].to=v;e[tot].w=wi;
}
void spfa()
{
    int head=0,tail=1;
    q[head]=minn;dis[minn]=0;vis[minn]=1;
    while(head!=tail){
        int x=q[head];head++;if(head>=1001)head=0;
        for(int i=first[x];i;i=e[i].next){
            int to=e[i].to;
            if(dis[to]<dis[x]+e[i].w){
                dis[to]=dis[x]+e[i].w;
                if(!vis[to]){
                    vis[to]=1;
                    q[tail]=to;
                    tail++;
                    if(tail>=1001)tail=0;
                }
            }
        }
        vis[x]=0;
    }
}
int main()
{
    int n=read(),a,b;
    for(int i=1;i<=n;i++){
        a=read();b=read();
        add(a,b+1,2);
        minn=min(minn,a);
        maxx=max(maxx,b+1);
    }
    for(int i=minn;i<=maxx;i++){
        add(i,i+1,0);
        add(i+1,i,-1);
    }
    memset(dis,-127,sizeof(dis));
    memset(vis,0,sizeof(vis));
    spfa();
    printf("%d",dis[maxx]);
    return 0;
} 

POJ1716差分约束版

解法二:贪心

分析:其实这道题贪心更好写而且可以跑得更快。先把每段区间按照右端点从小到大排序,贪心的基本策略就是尽量取这个区间最后两个整数。这里需要两个变量x和y,x初始化为第一个区间的倒数第二个元素,y为倒数第一个元素。每次枚举到下一个区间时,若该区间已经包含有x和y这两个元素,则直接跳转到下一个区间;若只包含了其中一个元素(因为x<y所以该元素必然是y),则x=y,y=e[i].b,同时sum++;若两个元素都不包含,则将x和y重新更新为当前区间的最后两个值,同时sum+2。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn=1e4+5;
using namespace std;
struct point{
    int a,b;
}e[maxn];
int read()
{
    int ans=0,f=1;char c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+c-48;c=getchar();}
    return ans*f;
}
bool cmp(point c,point d){return c.b<d.b;}
int main()
{
    int n=read(),x,y,sum=2;
    for(int i=1;i<=n;i++){
        e[i].a=read();e[i].b=read();
    }
    sort(e+1,e+1+n,cmp);
    x=e[1].b-1;y=e[1].b;
    for(int i=2;i<=n;i++){
        if(e[i].a<=x)continue;
        if(e[i].a<=y){
            sum++;x=y;y=e[i].b;continue;
        }
        x=e[i].b-1;y=e[i].b;sum+=2;
    }
    printf("%d",sum);
    return 0;
} 

POJ1716贪心版

时间: 2024-08-16 08:51:19

【POJ1716】Integer Intervals——差分约束||贪心的相关文章

poj1716 Integer Intervals(差分约束)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Integer Intervals Time Limit: 1000MS   Memory Limit: 10000K Description An integer interval [a,b], a < b, is a set of all consecutive integers beginning with a and ending with b. Write a prog

「POJ1201」Intervals - 差分约束

->戳我进原题 *** Intervals Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 30393 Accepted: 11768 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, the

POJ 2101 Intervals 差分约束

Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27746   Accepted: 10687 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, their end points and

POJ 1201 Intervals 差分约束

http://poj.org/problem?id=1201 TLE了很久,因为用了cin..... 思路和其他差分约束差不多,http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 如果区间[a, b]中至少有c个元素,如果用上面的博客,那么说明xa - xb >= c,但是注意这里是闭区间,xa - xb是不包括b这个点的, 就比如用了[a, b]有c个元素,[b, d]有x个,那么ans = c + x - 1个,

poj1201/zoj1508/hdu1384 Intervals(差分约束)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Intervals Time Limit: 10 Seconds      Memory Limit: 32768 KB You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: > reads the number of interva

poj1201 Intervals——差分约束

题目:http://poj.org/problem?id=1201 差分约束裸题: 设 s[i] 表示到 i 选了数的个数前缀和: 根据题意,可以建立以下三个限制关系: s[bi] >= s[ai-1] + ci ( 1 <= i <= n) s[i] >= s[i-1] + 0 ( 1 <= i <= mx) s[i-1] >= s[i] + (-1) (1 <= i <= mx) 然后求最长路,可以发现其中的 dis 值不会多余增大,也就满足题意要

poj1716 Integer Intervals 贪心

#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; struct node { int left,right; }c[10005]; bool cmp(node x,node y)//按照右端点排序 { if(x.right<y.right) return true; if(x.right==y.right&&x.left<y.lef

POJ1716 Integer Intervals

Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13984   Accepted: 5943 Description An integer interval [a,b], a < b, is a set of all consecutive integers beginning with a and ending with b. Write a program that: finds the minimal number

hdu 1384 Intervals (差分约束)

/* 给你 n 个区间 [Ai, Bi],要求从每一个区间中至少选出 Ci 个数出来组成一个序列 问:满足上面条件的序列的最短长度是多少? 则对于 不等式 f(b)-f(a)>=c,建立 一条 b 到 a 的边 权值为 c,则求的最长路 即为 最小值(集合) 而且有隐含条件:0<=f(a)-f(a-1)<=1 则有边权关系(a,a-1,0)以及(a-1,a,-1); */ /* 一般地,差分约束系统分两类:求最大差和最小差 1.求最大差 建立形如 A-B<=C 的不等式.在原图中加