Description
有一个整数序列,它的每个数各不相同,我们不知道它的长度(即整数个数),但我们知道在某些区间中至少有多少个整数,用区间(Li,Ri,Ci)来描述,表示这个整数序列中至少有Ci个数来自区间[Li,Ri],给出若干个这样的区间,问这个整数序列的长度最少能为多少?
Input
第一行一个整数N,表示区间个数;
接下来N行每行三个整数(Li,Ri,Ci),描述一个区间。
Output
仅一个数,表示该整数序列的最小长度。
Sample Input
4
4 5 1
6 10 3
7 10 3
5 6 1
Sample Output
4
Hint
N≤1000,
0≤Li≤Ri≤1000 ,
1≤Ci≤Ri-Li+1
Solution
本题是贪心的题。
我们可以按右端点大小从小到大排序,如果当前区间已经满足要求,那么它其中的数的位置可以任意摆放。
又因为之后区间的右端点的值比当前区间右端点的值大,所以可以贪心地选择当前区间最右端的数,这样可以尽量满足后面区间的条件。
当然还能用差分做,我太菜了不会
Code
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 inline int read()//快读 6 { 7 int f=1,x=0; 8 char c=getchar(); 9 10 while(c<'0' || c>'9') 11 { 12 if(c=='-')f=-1; 13 c=getchar(); 14 } 15 16 while(c>='0' && c<='9') 17 { 18 x=x*10+c-'0'; 19 c=getchar(); 20 } 21 22 return f*x; 23 } 24 25 struct Seq//定义结构体 26 { 27 int l,r,c;//分别为左端点、右端点和至少有几个数 28 } a[1005]; 29 30 int n,ans,sum,s,cnt,p,v[5005]; 31 32 inline int cmp(Seq x,Seq y)//排序所用的cmp函数 33 { 34 return x.r<y.r; 35 } 36 37 int main() 38 { 39 n=read(); 40 41 for(register int i=1; i<=n; i++) 42 { 43 a[i].l=read(),a[i].r=read(),a[i].c=read(); 44 } 45 46 sort(a+1,a+1+n,cmp);//排序 47 48 for(register int i=1; i<=n; i++)//开始贪心 49 { 50 ans=0; 51 52 for(register int j=a[i].l; j<=a[i].r; j++) 53 { 54 if(v[j])//如果被访问过 55 { 56 ++ans;//记录的数加1 57 } 58 } 59 60 if(ans<a[i].c)//如果记录的数还比要求的数少 61 { 62 for(register int j=a[i].r; j>=a[i].l; j--) 63 { 64 if(!v[j])//如果没有被访问 65 { 66 ++cnt,++ans,v[j]=1;//答案加1,多记录1个数,并且标记为已访问 67 68 if(ans==a[i].c)//如果已经满足了要求 69 { 70 break;//退出 71 } 72 } 73 } 74 } 75 } 76 77 printf("%d",cnt);//输出答案 78 79 return 0;//结束 80 }