• 加分二叉树


    具体解释在代码内

    区间动归,F[i,j]表示i到j这个区间的最优解,g[i,j]表示这个区间最优解内的情况下的根结点

    f[i,j]:=max(f[i,k-1]*f[k+1,j]+a[k]),k为区间内枚举

    k可以恰好为i或j这两个端点,此时需要特殊处理,即价值为f[i,j]:=1*f[i+1,j]+a[i]   (k取i时)

     1 {加分二叉树}
    2 program sky;
    3 var {int64}
    4 i,j,k,n,tp:longint;
    5 g:array[0..31,0..31] of int64;{注意f数组要开int64}
    6 f:array[0..31,0..31] of int64;
    7 a:array[0..31] of int64;
    8 function max(qq,ww:int64):int64;{function要开……}
    9 begin
    10 if qq>ww then exit(qq); exit(ww);
    11 end;
    12 procedure print(l,r:longint);{这么个遍历的小程序都纠结了一会}
    13 begin
    14 write(g[l,r],' ');
    15 if l<=g[l,r]-1 then print(l,g[l,r]-1);{if怎么加的问题……}
    16 if r>=g[l,r]+1 then print(g[l,r]+1,r);
    17 end;
    18 begin
    19 assign(input,'tree.in'); reset(input);
    20 assign(output,'tree.out'); rewrite(output);
    21 readln(n);
    22 for i:=1 to n do read(a[i]);
    23 for i:=1 to n do f[i,i]:=a[i];{f[i,i]g和[i,i]都要赋初值,因为走不到,而靠程序自己走到的话会出错,更新将是对一个f[i,i]以i为根f[i,i]:=1*1+a[i],因为左右子树都是0,即f[i,i-1]和f[i+1,i]}
    24 for i:=1 to n do g[i,i]:=i;
    25 for i:=n downto 1 do{downto,正向循环的话一开始就把F[1,n]跟新了,此时后面的状态还没出完全,不可能是对的}
    26 for j:=i to n do
    27 if i<>j then{即上述情况}
    28 for k:=i to j do
    29 begin
    30 tp:=f[i,j];
    31 f[i,j]:=max(max(1,f[i,k-1])*max(1,f[k+1,j])+a[k],f[i,j]);{当只有一个儿子的时候}
    32 if f[i,j]>tp then g[i,j]:=k;{记录方案}
    33 end;
    34 writeln(f[1,n]);
    35 print(1,n);
    36 close(input); close(output);
    37 end.

    skysun原创,转载请注明出处 http://www.cnblogs.com/skysun

  • 相关阅读:
    Java编程的逻辑 (42)
    Java编程的逻辑 (41)
    Java编程的逻辑 (40)
    Java编程的逻辑 (39)
    Java编程的逻辑 (38)
    Java编程的逻辑 (37)
    Java编程的逻辑 (36)
    Java编程的逻辑 (35)
    Java编程的逻辑 (31)
    web前端学习(二)html学习笔记部分(6)--fileAPI
  • 原文地址:https://www.cnblogs.com/skysun/p/2404701.html
Copyright © 2020-2023  润新知