首页 > 代码库 > SCOI2010 and SXOI2014 股票交易(DP)

SCOI2010 and SXOI2014 股票交易(DP)

明显的单调队列……

但下面的程序一直有bug

附上题解:http://blog.csdn.net/njlcazl/article/details/8611042

附上我的代码:

 1 var head,tail,i,n,maxp,w,t,ans,j:longint;
 2     as,bs,ap,bp,q,val:array[0..2020] of longint;
 3     f:array[0..2020,0..2020] of longint;
 4 function max(x,y:longint):longint;
 5  begin
 6  if x>y then exit(x) else exit(y);
 7  end;
 8 procedure init;
 9  begin
10  readln(n,maxp,w);ans:=0;
11  for i:=1 to n do readln(ap[i],bp[i],as[i],bs[i]);
12  end;
13 procedure main;
14  begin
15  fillchar(f,sizeof(f),128);
16  f[0,0]:=0;
17  for i:=1 to n do
18   begin
19    for j:=0 to as[i] do f[i,j]:=-j*ap[i];
20    for j:=0 to as[i] do
21     f[i,j]:=max(f[i,j],f[i-1,j]);
22    t:=i-w-1;
23    if t>=0 then
24     begin
25      head:=0;tail:=0;
26      for j:=0 to maxp do
27       begin
28        while (head<tail) and (q[head]<j-as[i]) do inc(head);
29        while (head<tail) and (f[t,j]+j*ap[i]>=val[tail-1]) do dec(tail);
30        val[tail]:=f[t,j]+j*ap[i];
31        q[tail]:=j;inc(tail);
32        if head<tail then f[i,j]:=max(f[i,j],val[head]-j*ap[i]);
33       end;
34      head:=0;tail:=0;
35      for j:=maxp downto 0 do
36       begin
37        while (head<tail) and (q[head]>j+bs[i]) do inc(head);
38        while (head<tail) and (f[t,j]+j*bp[i]>=val[tail-1]) do dec(tail);
39        val[tail]:=f[t,j]+j*bp[i];
40        q[tail]:=j;inc(tail);
41        if head<tail then f[i,j]:=max(f[i,j],val[head]-j*bp[i]);
42       end;
43      end;
44     ans:=max(ans,f[i,0]);
45    end;
46  writeln(ans);
47  end;
48 begin
49  init;
50  main;
51 end.                                          
View Code

还有另一位oier的代码:

 1 type
 2   ji=record
 3   w,s:longint;
 4 end;
 5 var
 6   q:array[0..2005] of ji;
 7   f:array[-2000..2000,0..2000] of longint;
 8   x,i,j,k,head,tail,t,maxp,w,api,bpi,asi,bsi:longint;
 9 
10 function max(x,y:longint):longint;
11 begin
12   if x>y then exit(x);
13   exit(y);
14 end;
15 
16 begin
17   readln(t,maxp,w);
18   for i:=-t to t do
19     for j:=1 to maxp do
20       f[i,j]:=-1000000000;
21   for i:=1 to t do
22     begin
23       readln(api,bpi,asi,bsi);
24       head:=1;
25       tail:=1;
26       f[i]:=f[i-1];
27       q[1].s:=0;
28       q[1].w:=f[i-w-1,0];
29       for j:=1 to maxp do
30         begin
31           inc(tail);
32           q[tail].w:=f[i-w-1,j]+j*api;
33           q[tail].s:=j;
34           while (head<tail)and(q[tail-1].w<q[tail].w) do
35             begin
36               q[tail-1]:=q[tail];
37               dec(tail);
38             end;
39           while (head<=tail)and(q[tail].s<j-asi) do inc(head);
40           f[i,j]:=max(f[i,j],q[head].w-api*j);
41         end;
42       head:=1;
43       tail:=1;
44       q[1].s:=maxp;
45       q[1].w:=f[i-w-1,maxp]+maxp*bpi;
46       for j:=maxp-1 downto 0 do
47         begin
48           inc(tail);
49           q[tail].w:=f[i-w-1,j]+j*bpi;
50           q[tail].s:=j;
51           while (head<=tail)and(q[tail].w<x) do
52             begin
53               q[tail-1]:=q[tail];
54               dec(tail);
55             end;
56           while (head<=tail)and(q[head].s>j+bsi) do inc(head);
57           f[i,j]:=max(f[i,j],q[head].w-j*bpi);
58         end;
59     end;
60   writeln(f[t,0]);
61 end.                               
View Code

这两种代码方法是一样的,但求解的过程不一样,可以挑选自己喜欢的来写。

ps:这两个代码都有bug,在bzoj上都是wa……