SSL P1862 提高组 删数

题目大意:
N个不同的正整数数x1, x2, … xN 排成一排,我们可以从左边或右边去掉连续的i个数(只能从两边删除数),1<=i<=n,剩下N-i个数,再把剩下的数按以上操作处理,直到所有的数都被删除为止。
若要删除区间[i,k],操作价值为则|xi – xk|*(k-i+1),如果只去掉一个数,操作价值为这个数的值。
求操作的最大价值。

3<=N<=100
N个操作数为1..1000 之间的整数。

题解:
区间DP:
f[i,j]表示删除区间[i,j]的最大操作值。
然后
初值:
f[i,i]=a[i]
f[i,j]=(a[j]-a[i])*(j-i+1) i<>j
然后就枚举[i,j]中一个点k找最优解:
f[i,j]=max(f[i,j],f[i,k]+f[k+1,j])
时间复杂度:O(N^3)

var 
     f:array [0..101,0..101] of longint;
     a:array [0..101] of longint;
     n,i,j,k:longint;

function num(aa,bb:longint):longint;
begin
      if aa=bb
         then exit(a[aa])
         else exit(abs(a[aa]-a[bb])*(bb-aa+1));
end;


function max(aa,bb:longint):longint;
begin
      if aa>bb then exit(aa);
      exit(bb);
end;

begin
      readln(n);
      for i:=1 to n do read(a[i]);
      for i:=1 to n do f[i,i]:=a[i];
      for i:=n downto 1 do
        for j:=i+1 to n do
          begin
            f[i,j]:=abs(a[j]-a[i])*(j-i+1);
            for k:=i to j do
               f[i,j]:=max(f[i,j],f[i,k]+f[k+1,j]);
          end;
      writeln(f[1,n]);
end.

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