三色二叉樹 解題報告

問題描述

一棵二叉樹可以按照如下規則表示成一個由0、1、2組成的字符序列,我們稱之為「二叉樹序列S」。

例如,下圖所表示的二叉樹可以用二叉樹序列S=21200110來表示。

你的任務是要對一棵二叉樹的節點進行染色。每個節點可以被染成紅色、綠色或藍色。並且,一個節點與其子節點的顏色必須不同,如果該節點有兩個子節點,那麼這兩個子節點的顏色也必須不相同。

給定一棵二叉樹的二叉樹序列,請求出這棵樹中最多和最少有多少個點能夠被染成綠色。

輸入文件

輸入文件名:TRO.IN

輸入文件僅有一行,不超過10000個字符,表示一個二叉樹序列。

輸出文件

輸出文件名:TRO.OUT

輸出文件也只有一行,包含兩個數,依次表示最多和最少有多少個點能夠被染成綠色。

樣例輸入 1122002010

樣例輸出 5 2

思路分析

簡單的樹形動態規劃。這三種顏色是平級的。所謂多少個點能夠被染成綠色,其實染成什麼色都一樣。

對於一顆樹,分為兩種情況考慮:

  1. 父親染成綠色,則數量為兩個子樹不染成綠色的數量之和+1。
  2. 父親不染成綠色,則數量為兩個子樹一個染成綠色,另一個不染成綠色的數量之和的最大值或最小值。

這個題目的建樹過程也需要注意。

完整代碼

//By Ceeji 
//Date: 2009-3-12 
//HAOI test 2 - Problem 2 
//Type: Tree DP 
//State: Accepted

Program tro; 
Type node=record 
            l,r:longint; 
          end; 
Var str:ansistring; 
    ch:char; 
    i,j,k,len,n,key,nn:longint; 
    a:array[1..30000]of node; // tree 
    dp:array[1..30000,1..4]of longint; //1: has green 2:not has green 
    b:array[1..30000]of boolean; 

Function max(i,j:longint):longint; 
begin 
    if i>j then exit(i) else exit(j); 
end; 

Function min(i,j:longint):longint; 
begin 
    if i<j then exit(i) else exit(j); 
end; 

Procedure maketree(j:longint); 
var c:char; 
begin 
    c:=str[n]; 
    if c='0' then 
    begin 
       exit; 
    end; 
    if c='1' then 
    begin 
       inc(n); 
       a[j].l:=n; 
       a[j].r:=0; 
       maketree(n); 
       exit; 
    end; 
    if c='2' then 
    begin 
       inc(n); 
       a[j].l:=n; 
       maketree(n); 
       inc(n); 
       a[j].r:=n; 
       maketree(n); 
    end; 
end; 

Procedure work(i:longint); 
begin 
    if b[i] then exit; 
    b[i]:=true; 
    if a[i].l=0 then begin dp[i,1]:=0; dp[i,2]:=1; dp[i,3]:=0; dp[i,4]:=1; exit; end 
    else begin 
        work(a[i].l); 
        if a[i].r<>0 then work(a[i].r); 
        dp[i,1]:=max(dp[a[i].l,2]+dp[a[i].r,1],dp[a[i].l,1]+dp[a[i].r,2]); 
        dp[i,2]:=dp[a[i].l,1]+dp[a[i].r,1]+1; 
        dp[i,3]:=min(dp[a[i].l,3]+dp[a[i].r,4],dp[a[i].l,4]+dp[a[i].r,3]); 
        dp[i,4]:=dp[a[i].l,3]+dp[a[i].r,3]+1; 
    end; 
end;

begin 
    assign(input,'tro.in');    reset(input); 
    assign(output,'tro.out');  rewrite(output); 
    readln(str); 
    fillchar(a,sizeof(a),0); 
    fillchar(dp,sizeof(dp),0); 
    len:=length(str); 
    n:=1; key:=1; 
    maketree(1); 
    str:=''; 
    work(1); 
    writeln(max(dp[1,1],dp[1,2]),' ',min(dp[1,3],dp[1,4])); 
    close(output); 
end.
当前页阅读量为: