【CF713C】Sonya and Problem Wihtout a Legend(离散化,DP)
题意:给你一个数列,对于每个数字你都可以++或者−−
然后花费就是你修改后和原数字的差值,然后问你修改成一个严格递增的,最小花费
思路:很久以前做过一道一模一样的
严格递增很难处理,就转化为非严格递增处理
设a[i]<a[j],i<j
a[j]-a[i]>=j-i
a[j]-j>=a[i]-i
即将a[i]转化为a[i]-i处理
非严格递增情况下最终数列一定是由原先的数组成的,不可能出现某两个原数中间的值
dp[i,j]为第i位,结尾为第j大的数,转化成这样的数列的最小费用
dp[i,j]=min(dp[i-1,k]+abs(a[i]-b[j])) k<=j
第一项用前缀和优化
1 const oo=10000000000000; 2 var dp,f:array[0..3000,0..3000]of int64; 3 a,b:array[1..3000]of longint; 4 n,i,j:longint; 5 ans:int64; 6 7 function min(x,y:int64):int64; 8 begin 9 if x<y then exit(x); 10 exit(y); 11 end; 12 13 procedure qsort(l,r:longint); 14 var i,j,t,mid:longint; 15 begin 16 i:=l; j:=r; mid:=b[(l+r)>>1]; 17 repeat 18 while mid>b[i] do inc(i); 19 while mid<b[j] do dec(j); 20 if i<=j then 21 begin 22 t:=b[i]; b[i]:=b[j]; b[j]:=t; 23 inc(i); dec(j); 24 end; 25 until i>j; 26 if l<j then qsort(l,j); 27 if i<r then qsort(i,r); 28 end; 29 30 begin 31 //assign(input,'1.in'); reset(input); 32 // assign(output,'1.out'); rewrite(output); 33 readln(n); 34 for i:=1 to n do 35 begin 36 read(a[i]); 37 a[i]:=a[i]-i; 38 end; 39 b:=a; 40 qsort(1,n); 41 for i:=1 to n do 42 begin 43 for j:=0 to n do f[i,j]:=oo; 44 for j:=1 to n do 45 begin 46 dp[i,j]:=abs(a[i]-b[j])+f[i-1,j]; 47 f[i,j]:=min(f[i,j-1],dp[i,j]); 48 end; 49 end; 50 ans:=oo; 51 for i:=1 to n do ans:=min(ans,dp[n,i]); 52 writeln(ans); 53 //close(input); 54 // close(output); 55 end.
null