• 序列


    序列(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.
    我的正解
  • 相关阅读:
    华强北三代悦虎1562A怎么样?
    改丝印的假华强北三代1562A,用芯良苦!
    华强北三代过软件检测的佳和1562A
    Unlua静态导出
    Unlua编程基础
    Android JNI调用
    手机屏幕参数
    UE4 stats性能埋点
    【JWT】JSON Web Token
    【算法】一致性哈希算法实现
  • 原文地址:https://www.cnblogs.com/vacation/p/6040366.html
Copyright © 2020-2023  润新知