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 integers c1, ..., cn from the standard input,
computes the
minimal size of a set Z of integers which has at least ci common elements with
interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard
output.
题目大意:一个整数集合Z有n个区间,每个区间有3个值,ai,bi,ci代表,在区间[ai,bi]上至少有ci个整数属于集合Z,ci可以在区间内任意取不重复的点。
现在要满足所有区间的约束条件,问最少可选多少个点。
The first line of the input contains an integer n (1 <= n <= 50000) --
the number of intervals. The following n lines describe the intervals. The
(i+1)-th line of the input contains three integers ai, bi and ci separated by
single spaces and such that 0 <= ai <= bi <= 50000 and 1 <= ci <=
bi - ai+1.
第一行一个整数n,表示区间个数
以下n行描述区间,第i+1行,三个整数ai,bi,ci,由空格隔开,其中 0 <= ai <= bi <= 50000 且1 <=
ci <= bi - ai+1.
The output contains exactly one integer equal to the minimal size of set Z
sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.
一行,输出满足要求序列的长度的最小值
题目意思是说在{ai,bi}区间和Z点集有ci个共同元素,设Si表示区间{0,i}有多少个元素,那么根据题目意思:Sbi-Sai>=ci。但是我们发现这远远不够,根本没法将所有点连接起来。所以此时我们再看一下Si的定义,易写出0<=Si-S(i-1)<=1。
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<algorithm>
5 using namespace std;
6 struct p{
7 int to,v,nxt;
8 }edge[500001];
9 int n,maxx,minn,cnt,a,b,c,dis[1000001],queue[10000001],heads[1000001],head,tail;
10 bool vis[1000001]={0};
11 int addEdge(int u,int v,int val)//链式前向星
12 {
13 edge[++cnt].to=v;
14 edge[cnt].v=val;
15 edge[cnt].nxt=heads[u];
16 heads[u]=cnt;
17 }
18 int main()
19 {
20 scanf("%d",&n);
21 maxx=-0x7fffffff,minn=0x7fffffff;
22 for(int i=1;i<=n;i++)
23 {
24 scanf("%d%d%d",&a,&b,&c);
25 addEdge(a-1,b,c);
26 minn=min(minn,a-1);
27 maxx=max(maxx,b);
28 }
29 for(int i=minn;i<=maxx;i++)
30 {
31 addEdge(i-1,i,0);
32 addEdge(i,i-1,-1);
33 }
34 for(int i=0;i<=maxx;++i) dis[i]=-10000000;
35 dis[minn]=0,queue[1]=minn,tail=1,vis[minn]=1;
36 do
37 {
38 head++;
39 int node=queue[head];
40 for(int i=heads[node];i!=0;i=edge[i].nxt)
41 {
42 int to=edge[i].to,val=edge[i].v;
43 if(dis[to]<dis[node]+val)
44 {
45 dis[to]=dis[node]+val;
46 if(!vis[to])
47 {
48 tail++;
49 queue[tail]=to;
50 vis[to]=1;
51 }
52 }
53 }
54 vis[node]=0;
55 }while(head!=tail);
56 printf("%d\n",dis[maxx]);
57 }