bzoj2298

不难发现必然是两个人之间话产生矛盾或自身话有问题
很显然,当ai>aj时,若ai<n-bj时i,j两人话矛盾
ai<ai<n-bj,这东西有没有数轴上的线段的既视感?
我们只要求出做多不相交的线段就可得到最少谎话数

 1 var a,b,f:array[0..100010] of longint;
 2     i,j,k,n:longint;
 3 
 4 function min(a,b:longint):longint;
 5   begin
 6     if a>b then exit(b) else exit(a);
 7   end;
 8 
 9 function max(a,b:longint):longint;
10   begin
11     if a>b then exit(a) else exit(b);
12   end;
13 
14 procedure swap(var a,b:longint);
15   var c:longint;
16   begin
17     c:=a;
18     a:=b;
19     b:=c;
20   end;
21 
22 procedure sort(l,r:longint);
23   var i,j,x,y:longint;
24   begin
25     i:=l;
26     j:=r;
27     x:=b[(l+r) shr 1];
28     y:=a[(l+r) shr 1];
29     repeat
30       while (b[i]<x) or (b[i]=x) and (a[i]<y) do inc(i);
31       while (x<b[j]) or (b[j]=x) and (y<a[j]) do dec(j);
32       if not(i>j) then
33       begin
34         swap(a[i],a[j]);
35         swap(b[i],b[j]);
36         inc(i);
37         dec(j);
38       end;
39     until i>j;
40     if l<j then sort(l,j);
41     if i<r then sort(i,r);
42   end;
43 
44 begin
45   readln(n);
46   for i:=1 to n do
47   begin
48     readln(a[i],b[i]);
49     b[i]:=n-b[i];
50   end;
51   sort(1,n);
52   j:=1;
53   for i:=1 to n do
54   begin
55     f[i]:=f[i-1];
56     while b[j]=i do
57     begin
58       k:=j+1;
59       while (a[k]=a[j]) and (b[k]=b[j]) do inc(k);
60       f[i]:=max(f[i],f[a[j]]+min(k-j,b[j]-a[j]));  //注意这个地方相同分数的数目
61       j:=k;
62     end;
63   end;
64   writeln(n-f[n]);
65 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4472952.html