普通sequence

题目

首先是一个数据范围为2000的,这个可以用平方算法做。

要使它成为一个非降序列的合并次数最小,我们可以贪心地想到要使合并后的值尽量小,不然就会导致后面需要的合并次数增多。

我们用c[i]记录前缀和,f[i]表示以i结尾的这一段序列的最后一个元素的值,g[i]表示到i为止的合并次数,那么就可以得到一个转移方程。

f[i]=c[i]-c[j](f[j]<=c[i]-c[j])

g[i]=g[j]+i-j-1;

因为c[i]-c[j]在downto的过程中是单调递增的,所以只要找到一个可以转移的就可以break了。

View Code
program Neayo;
const
        inf='sequence.in';
        ouf='sequence.out';
var
        i,j,k,m,n,ans:longint;
        g,f,c:array[0..1502]of longint;
procedure init;
var x:longint;
begin
     assign(input,inf);assign(output,ouf);
     reset(input);rewrite(output);
     readln(n);
     for i:=1 to n do
     begin
          read(x);
          c[i]:=c[i-1]+x;
     end;
     close(input);
end;
procedure go;
begin
     fillchar(f,sizeof(f),127);
     f[0]:=0;g[0]:=0;
     for i:=1 to n do
      for j:=i-1 downto 0 do
      if c[i]-c[j]>=f[j] then
      begin
           f[i]:=c[i]-c[j];
           g[i]:=g[j]+i-j-1;
           break;
      end;
    writeln(g[i]);
end;
begin
     init;
     go;
     close(output);
end.

到了1000000的数据范围,平方算法是绝对不可行的了。

但是转移方程还是正确的,由于它的单调性,于是我们加入单调队列将决策过程优化成O(nlogn)。

View Code
 1 const
 2         inf='ccl.in';
 3         ouf='ccl.out';
 4 var
 5         i,j,k,n:longint;
 6         ans:longint;
 7         c:array[0..1000001]of int64;
 8         g,f,q:array[0..1000001]of int64;
 9 procedure init;
10 begin
11      assign(input,inf);assign(output,ouf);
12      reset(input);rewrite(output);
13      readln(n);
14      for i:=1 to n do
15      begin
16           read(c[i]);
17           c[i]:=c[i-1]+c[i];
18      end;
19      close(input);
20 end;
21 procedure go;
22 var l,r:longint;
23 begin
24      fillchar(f,sizeof(f),127);
25      l:=1;r:=1;f[0]:=0;q[1]:=0;
26      for i:=1 to n do
27      begin
28           while (l<r)and(c[i]>=f[q[l+1]])do inc(l);
29           f[i]:=c[i]-c[q[l]]+c[i];
30           g[i]:=g[q[l]]+i-q[l]-1;
31           while (r>l)and(f[i]<=f[q[r]])do dec(r);
32           inc(r);
33           q[r]:=i;
34      end;
35      writeln(g[n]);
36 end;
37 begin
38      init;
39      go;
40      close(output);
41 end.
posted @ 2012-11-06 16:11  neayo  阅读(221)  评论(0编辑  收藏  举报