改造二叉树(bst)

题目大意:给你一棵二叉树,让你改变最少的结点上的数值,使这棵二叉树变成BST,求这个需要改变的最少的结点数。

算法:二分+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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值