caioj·1075: 动态规划入门(中链式2:能量项链)

来源:互联网 发布:上杉升 知乎 编辑:程序博客网 时间:2024/06/03 17:08

caioj·1075: 动态规划入门(中链式2:能量项链)

时间限制: 1 Sec 内存限制: 128 MB

题目描述
【问题描述】

能量球组成的项链。相邻两球可以合并产生新球。合并规则:如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标记为m,尾标记为n。一条项链怎样合并才能得到最大能量,求最大能量值。

例如:设N=4, (2,3) (3,5) (5,10) (10,2)。

((4⊕1)⊕2)⊕3)=10*2*3+10*3*5+10*5*10=710。

【输入文件】

输入的第一行是一个正整数N(4≤N≤100)第二行是N个用空格隔开的正整数,所有的数均不超过1000。第i个数为第i颗珠子的头标记(1≤i≤N),当i

Solution

合并珠子,产生能量,输入头标记,尾标记为上一个珠子的头标记
求能量释放最大值

解释一下为什么要开两倍数组
比如2 3 5 10
存储两次为 2 3 5 10 2 3 5 10
这样从第二个开始起就可以遍历全部的情况如
3 5 10 2
5 10 2 3
10 2 3 5(答案)
一个小技巧

转移方程
f[l][r]:=max(f[l,r],f[l,k]+f[k+1][r]+a[l]*a[k+1]*a[r+1]);

Code

program handle;var  f:array[0..1100,1..1100]of longint;  a:array[1..1100]of longint;//两倍数组  n,i,j,ans,k,l,r:longint;function max(p,q:longint):longint;begin  if p>q then exit(p)  else exit(q);end;begin  readln(n);  for i:=1 to n do  begin    read(a[i]);    a[i+n]:=a[i];//开两倍数组这样可以连成链  end;  for i:=2 to 2*n do //枚举区间大小  begin    for l:=1 to 2*n-i+1 do//枚举左端点    begin      r:=l+i-1; //右端点      for k:=l to r-1 do//l<=k<r枚举区间断点        f[l][r]:=max(f[l,r],f[l,k]+f[k+1][r]+a[l]*a[k+1]*a[r+1]);    end;  end;  for i:=1 to n do  ans:=max(ans,f[i][i+n-1]); //DP完成后打擂台搜索答案  writeln(ans);  readln;  readln;end.
原创粉丝点击