序列

序列(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.
我的正解
原文地址:https://www.cnblogs.com/vacation/p/6040366.html