序列(sequence.pas/c/cpp)
【题目描述】
有一个整数序列,它的每个数各不相同,我们不知道它的长度是多少(即整数个数),但我们知道在某些区间中至少有多少个整数,用区间(Li,Ri,Ci)来描述,表示这个整数序列中至少有Ci个数来自区间[Li,Ri],给出若干个这样的区间,问这个整数序列的长度最少能为多少?
【输入文件】
第一行一个整数N,表示区间个数;
接下来N行,每行三个整数(Li,Ri,Ci),描述一个区间。
【输出文件】
仅一个数,表示该整数序列的最小长度。
【样例输入】
4
4 5 1
6 10 3
7 10 3
5 6 1
【样例输出】
4
【数据规模】
N≤1000,0≤Li≤Ri≤l000,1≤Ci≤Ri-Li+1
考试时这题根本不会做。。模拟了一个只有10分的算法
1 题目的意思是选择一些数,使得在[Li,Ri]中至少有C个数,目的是选尽量少的数满足所有的区间要求。可以将所有的区间按照右端点从小到大排序来考虑问题。对于当前的区间假设满足了它的要求,即这个区间中至少有Ci个数,那么怎么安排这些数的位置是无所谓的;又因为之后的区间都是右端点在当前这个区间右端点的右边区间,故贪心地选当前区间靠后的若干个数。这样不但可以满足当前区间的要求,还可以尽量满足后面区间的要求,并且这种贪心的方法是最优的。 2 时间效率: 3 我们要做的就是排序并且扫描,效率为O(Nlog2N+∑(Ri-Li))(1<=i<=n) 4 空间效率: 5 O(N)
1 program sequence; 2 var 3 n,i,same,ans:longint; 4 a,b,c:array[1..1050] of longint; 5 procedure sort(l,r:longint); 6 var i,j,x,y,tmp:longint; 7 begin 8 i:=l; 9 j:=r; 10 x:=a[(i+j) div 2]; 11 y:=b[(i+j) div 2]; 12 repeat 13 while ( a[i]<x ) or ( (a[i]=x) and (b[i]<y) ) do inc(i); 14 while ( a[j]>x ) or ( (a[j]=x) and (b[j]>y) ) do dec(j); 15 if i<=j then 16 begin 17 if (a[i]>a[j]) or ( (a[i]=a[j]) and (b[i]>b[j]) ) then 18 begin 19 tmp:=a[i]; a[i]:=a[j]; a[j]:=tmp; 20 tmp:=b[i]; b[i]:=b[j]; b[j]:=tmp; 21 tmp:=c[i]; c[i]:=c[j]; c[j]:=tmp; 22 end; 23 inc(i); 24 dec(j); 25 end; 26 until i>j; 27 if i<r then sort(i,r); 28 if l<j then sort(l,j); 29 end; 30 begin 31 assign(input,'sequence.in'); 32 reset(input); 33 assign(output,'sequence.out'); 34 rewrite(output); 35 readln(n); 36 for i:=1 to n do 37 readln(a[i],b[i],c[i]); 38 sort(1,n); writeln; 39 //for i:=1 to n do 40 //writeln(a[i],' ',b[i],' ',c[i]); 41 ans:=0; 42 for i:=1 to n-1 do 43 begin 44 if b[i]<a[i+1] then 45 begin inc(ans,c[i]); c[i]:=0; end 46 else 47 if b[i]>=a[i+1] then 48 begin 49 same:=b[i]-a[i+1]+1; 50 if same>=c[i] then begin inc(ans,c[i]); dec(c[i+1],c[i]); c[i]:=0; end 51 else if same<c[i] then begin inc(ans,c[i]); c[i]:=0; dec(c[i+1],same); end; 52 end; 53 end; 54 if c[n]>0 then inc(ans,c[n]); 55 writeln(ans); 56 close(input); 57 close(output); 58 //for i:=1 to n do write(c[i],' '); 59 end.
1 program sequence; 2 var 3 n,i,ans:longint; 4 l,r,c:array[1..1000] of longint; 5 f:array[1..1000] of boolean; 6 procedure init; 7 var i:longint; 8 begin 9 readln(n); 10 for i:=1 to n do readln(l[i],r[i],c[i]); 11 fillchar(f,sizeof(f),false); 12 end; 13 procedure sort(left,right:longint); 14 var i,j,tmp,x,y:longint; 15 begin 16 i:=left; 17 j:=right; 18 x:=l[(i+j) div 2]; 19 y:=r[(i+j) div 2]; 20 repeat 21 while (r[i]<y) or ((r[i]=y)and(l[i]<x)) do inc(i); 22 while (r[j]>y) or ((r[j]=y)and(l[j]>x)) do dec(j); 23 if i<=j then 24 begin 25 if (r[i]>r[j]) or ((r[i]=r[j])and(l[i]>l[j])) then 26 begin 27 tmp:=r[i]; r[i]:=r[j]; r[j]:=tmp; 28 tmp:=l[i]; l[i]:=l[j]; l[j]:=tmp; 29 tmp:=c[i]; c[i]:=c[j]; c[j]:=tmp; 30 end; 31 inc(i); 32 dec(j); 33 end; 34 until i>j; 35 if i<right then sort(i,right); 36 if left<j then sort(left,j); 37 end; 38 procedure outit; 39 var i:longint; 40 begin 41 {writeln; 42 for i:=1 to n do writeln(l[i],' ',r[i],' ',c[i]); 43 writeln; 44 for i:=1 to 10 do write(f[i],' '); } 45 ans:=0; 46 for i:=1 to 1000 do 47 if f[i] then inc(ans); 48 writeln(ans); 49 end; 50 procedure doit; 51 var i,j:longint; 52 begin 53 for i:=1 to n do 54 begin 55 for j:=r[i] downto l[i] do 56 if f[j] then dec(c[i]); 57 if c[i]>0 then 58 for j:=r[i] downto l[i] do 59 begin 60 if not(f[j]) then begin f[j]:=true; dec(c[i]); end; 61 if c[i]=0 then break; 62 end; 63 end; 64 {if f[j] then 65 begin 66 dec(c[i]); 67 if c[i]=0 then break; 68 end 69 else 70 begin 71 f[j]:=true; 72 dec(c[i]); 73 if c[i]=0 then break; 74 end;} 75 end; 76 begin 77 assign(input,'sequence.in'); 78 reset(input); 79 assign(output,'sequence.out'); 80 rewrite(output); 81 init; 82 sort(1,n); 83 doit; 84 outit; 85 close(input); 86 close(output); 87 end.