bzoj 1609 简单dp

    xiaoxiao2021-03-25  104

    题意:n个数,要求从形成单调不减或单调不增的序列,求最少改变多少个数

    用f[i,j]表示第i头牛编号为j时的最小修改次数

    因为正反均可,所以做正反两遍取min

    转移方程 :

    从左到右 :f[i,j]=min{f[i-1,k] + (a[i] != j)}  (k<=j)  边界:f[0,1] = f[0,2] = f[0,3] = f[1,a[1]] =0

    从右往左: f[i,j]=min{f[i+1,k] + (a[i] != j)} (j<=j)  边界:f[n+1,1] = f[n+1,2] = f[n+1,3] = f[n,a[n]] =0

    var n,t1,t2 :longint; i,j,k :longint; f :array[0..30010,0..3] of longint; a :array[0..30010] of longint; function min(a,b:longint):longint; begin if a<b then exit(a) else exit(b); end; begin read(n); for i:=1 to n do read(a[i]); fillchar(f,sizeof(f),127); f[0,1]:=0; f[0,2]:=0; f[0,3]:=0; f[1,a[1]]:=0; for i:=1 to n do for j:=1 to 3 do begin for k:=1 to j do if a[i]=j then f[i,j]:=min(f[i,j],f[i-1,k]) else f[i,j]:=min(f[i,j],f[i-1,k]+1); end; t1:=min(f[n,1],f[n,2]); t1:=min(t1,f[n,3]); // fillchar(f,sizeof(f),127); f[n+1,1]:=0; f[n+1,2]:=0; f[n+1,3]:=0; f[n,a[n]]:=0; for i:=n downto 1 do for j:=1 to 3 do begin for k:=1 to j do if a[i]=j then f[i,j]:=min(f[i,j],f[i+1,k]) else f[i,j]:=min(f[i,j],f[i+1,k]+1); end; t2:=min(f[1,1],f[1,2]); t2:=min(t2,f[1,3]); writeln(min(t1,t2)); end. ——by Eirlys

    转载请注明原文地址: https://ju.6miu.com/read-25989.html

    最新回复(0)