最小代价树(动态规划)

Description

  以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和。 
  例如:((4+1)+ (2+3))=((5)+(5))=10。除去原数不4,1,2,3之外,其余都为中间结果,如5,5,10,将中间结果相加,得到:5+5+10=20,那么数20称为此数列的一个代价,若得到另一种算法:(4+((1+2)+3))=(4+((3)+3))=(4+(6))=10,数列的另一个代价为:3+6+10=19。若给出N个数,可加N-1对括号,求出此数列的最小代价。 
注:结果范围不超出longint. 

Input

第一行为数N(1≤N≤200),第二行为N个正整数,整数之间用空格隔开。

Output

输出仅一行,即为最少代价值。

Sample Input

 

 
   

 

Sample Output

 

 
   
 
 
 
   
f[i,j]表示把第i个数和第j个数合并的最优值,状态转移方程为:
f[i,j]=min{f[i,j],f[i,k]+f[k+1,j]+s[j]-s[i-1]}
(n>=i>=1,i<=k
f[1,n]即为所求。
时间复杂度:O(n^3)
 
 
 
   

const
  maxn=200;
var
  f,sum:array[0..200,0..200]of longint;
  a:array[0..200]of longint;
  n,i,j,k,l:longint;

function min(a,b:longint):longint;
begin
  if a
end;

begin
  readln(n);
  for i:=1 to n do
    read(a[i]);
  for i:=1 to n do
    begin
      f[i,i]:=0;
      sum[i,i]:=a[i];
      for j:=i+1 to n do
        sum[i,j]:=sum[i,j-1]+a[j];
    end;
  for l:=2 to n do
    for i:=1 to n-l+1 do
    begin
      j:=l+i-1;
      f[i,j]:=maxlongint;
      for k:=i to j-1 do
        f[i,j]:=min(f[i,j],f[i,k]+f[k+1,j]+sum[i,j]);
    end;
  writeln(f[1,n]);
end.

 

 

 

版权属于: Chris

原文地址: http://blog.sina.com.cn/s/blog_83ac6af80102vjrp.html

转载时必须以链接形式注明原始出处及本声明。

你可能感兴趣的:(动态规划)