第一问类似最长上升序列,只不过因为要满足能修改所以不能直接求
比如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.