题目大意:给你一棵二叉树,让你改变最少的结点上的数值,使这棵二叉树变成BST,求这个需要改变的最少的结点数。
算法:二分+DP
一开始就没理解题目问的真正内涵,想了半天的树型DP,结果肯定是果断不对,看了题解才知道BST就是二叉树中序遍历之后保持有序,进一步得知其实就是要我们求LIS。。
将这棵二叉树中序遍历,然后再求它的LIS即可。最后用总的-最长上升的就是需要最少的需要改变的。
算法:二分+DP
一开始就没理解题目问的真正内涵,想了半天的树型DP,结果肯定是果断不对,看了题解才知道BST就是二叉树中序遍历之后保持有序,进一步得知其实就是要我们求LIS。。
将这棵二叉树中序遍历,然后再求它的LIS即可。最后用总的-最长上升的就是需要最少的需要改变的。
下面是70分的代码,未AC。。。
program bst;
const
maxn=100000;
var
a,f,lc,rc,ans,miku:array [0..maxn] of longint;
n,tot:longint;
procedure init;
var
i,x:longint;
begin
fillchar(ans,sizeof(ans),0);
readln(n);
for i:=1 to n do read(a[i]);
for i:=2 to n do
begin
readln(f[i],x);
if x=0 then lc[f[i]]:=i else rc[f[i]]:=i;
end;
end;
procedure bianli(x:longint);
begin
if x=0 then exit;
bianli(lc[x]);
inc(tot);
ans[tot]:=a[x];
bianli(rc[x]);
end;
procedure main;
var
i,l,r,ika,mid:longint;
begin
ika:=0;
miku[0]:=-maxlongint;
for i:=1 to tot do
begin
if ans[i]>miku[ika] then
begin
inc(ika);
miku[ika]:=ans[i];
end
else
begin
l:=1;
r:=ika;
while l<r do
begin
mid:=(l+r) shr 1;
if ans[i]>miku[mid] then l:=mid+1 else r:=mid;
end;
if ans[i]<miku[l] then miku[l]:=ans[i];
end;
end;
writeln(n-ika);
end;
begin
assign(input,'bst.in'); reset(input);
assign(output,'bst.out'); rewrite(output);
init;
bianli(1);
main;
288

被折叠的 条评论
为什么被折叠?



