第一问类似最长上升序列,只不过因为要满足能修改所以不能直接求
比如2 3 4 4 5 最长上升序列长是4,但是最少修改是2,因为一个这个最长上升序列不能保持不变
因此我们对a[i]-i,然后求这个新序列ai的最长不下降序列即可
第二问我们设f[i]表示以位置i结尾的最长不下降序列长度
显然要满足修改最少的数显然一个修改区间是[j+1,i-1]满足f[i]=f[j]+1 且 a[j]<=a[i]
这里有一个性质,就是这个区间内一定最后刷成a[i]或a[j]
然后暴力搞,然后数据弱就过了

 1 const inf=1000000007;
 2 type node=record
 3        po,next:longint;
 4      end;
 5 
 6 var f,q,a,b,p:array[0..40010] of longint;
 7     v,c,d:array[0..40010] of int64;
 8     w:array[0..40010] of node;
 9     m,n,t,l,r,j,k,i:longint;
10 
11 function min(a,b:int64):int64;
12   begin
13     if a>b then exit(b) else exit(a);
14   end;
15 
16 begin
17   readln(n);
18   for i:=1 to n do
19   begin
20     read(a[i]);
21     a[i]:=a[i]-i;
22   end;
23   a[0]:=-inf;
24   t:=1;
25   q[1]:=1;
26   f[1]:=1;
27   for i:=2 to n do
28   begin
29     if (a[i]>=a[q[t]]) then
30     begin
31       inc(t);
32       f[i]:=t;
33       q[t]:=i;
34     end
35     else begin
36       l:=1;
37       r:=t;
38       while l<r do
39       begin
40         m:=(l+r) shr 1;
41         if a[i]<a[q[m]] then r:=m else l:=m+1;
42       end;
43       q[l]:=i;
44       f[i]:=l;
45     end;
46   end;
47   writeln(n-t);
48   inc(n);
49   a[n]:=inf;
50   f[n]:=t+1; //新增加一个无穷大的点方便统计
51   t:=0;
52   for i:=n+1 downto 0 do
53   begin
54     inc(t);
55     w[t].po:=i;
56     w[t].next:=p[f[i]];
57     p[f[i]]:=t; //记录满足f[j]+1=f[i]的点
58   end;
59   for i:=1 to n do
60   begin
61     j:=p[f[i]-1];
62     l:=w[j].po;
63     d[i]:=0;
64     for k:=i-1 downto l+1 do
65       d[k]:=d[k+1]+abs(a[k]-a[i]);
66     v[i]:=inf*inf;
67     while j<>0 do
68     begin
69       if w[j].po>i then break;
70       l:=w[j].po;
71       if a[l]<=a[i] then
72       begin
73         c[l]:=0;
74         for k:=l+1 to i-1 do
75           c[k]:=c[k-1]+abs(a[k]-a[l]);
76         for k:=l to i-1 do
77           v[i]:=min(v[i],c[k]+d[k+1]+v[l]);
78       end;
79       j:=w[j].next;
80     end;
81   end;
82   writeln(v[n]);
83 end.
View Code

 

posted on 2015-01-26 19:03  acphile  阅读(157)  评论(0编辑  收藏  举报