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.

还有另一位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.

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

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

SCOI2010 and SXOI2014 股票交易(DP),布布扣,bubuko.com

时间: 2024-08-22 16:33:22

SCOI2010 and SXOI2014 股票交易(DP)的相关文章

1855: [Scoi2010]股票交易[单调队列优化DP]

1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status][Discuss] Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每个i,都有APi>=

bzoj1855: [Scoi2010]股票交易--单调队列优化DP

单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w-1][k]+k*Ap[i]的单调性即可 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 2010; 6 int

BZOJ 1855 [Scoi2010]股票交易 单调队列优化DP

题意:链接 方法:单调队列优化DP 解析:噢又是一道情况很多的题,然而三种更新我又落下一种导致样例不过,后来看题解才恍然- -最SB的一种更新居然忘了. 状态好想f[i][j]代表前i天有j双袜子时的最大利润. 三种更新: 第一种:f[i][j]=max(f[i][j],f[i?1][j]):(然而我忘了这一种) 第二种:买入f[i][j]=max(f[i][j],f[i?w?1][k]?(j?k)?a[i].ap)(k>=j?a[i].as); 第三种:卖出f[i][j]=max(f[i][j

洛谷 [SCOI2010]股票交易 | 单调性DP

题目链接 #include<cstdio> #include<algorithm> #include<cstring> #define N 2005 using namespace std; int n,q[N],ap,bp,dp[N][N],as,bs,m,w; int main() { scanf("%d%d%d",&n,&m,&w); memset(dp,128,sizeof(dp)); for (int i=1;i&l

LUOGU P2569 [SCOI2010]股票交易(单调队列优化dp)

传送门 解题思路 不难想一个\(O(n^3)\)的\(dp\),设\(f_{i,j}\)表示第\(i\)天,手上有\(j\)股的最大收益,因为这个\(dp\)具有单调性,所以\(f_i\)可以贪心的直接从\(f_{i-w-1}\)那一层转移来,转移时枚举一下当前买卖多少.考虑优化,发现每次其实就是一个区间取\(max\),是由\(AS\)和\(BS\)所限制的区间,所以单调队列优化就好了,一个正着做一个倒着做,时间复杂度\(O(n^2)\) 代码 #include<bits/stdc++.h>

BZOJ1855 [Scoi2010]股票交易 【单调队列优化dp】

题目链接 BZOJ1855 题解 设\(f[i][j]\)表示第\(i\)天结束时拥有\(j\)张股票时的最大收益 若\(i \le W\),显然在这之前不可能有交易 \[f[i][j] = max\{f[i - 1][j],-ap[i] * j\} \quad [j \le as[i]]\] 否则,就有三种选择: ①购买 \[f[i][j] = max\{f[i - W - 1][k] - ap[i] * (j - k)\} \quad[k \le j][j - k \le as[i]]\]

[SCOI2010]股票交易

[SCOI2010]股票交易 推荐的相关题目显示 题目描述 最近 lxhgww 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww 预测到了未来 T 天内某只股票的走势,第 i 天的股票买入价为每股 APi?,第 i 天的股票卖出价为每股 BPi?(数据保证对于每个 i,都有 APi?≥BPi?),但是每天不能无限制地交易,于是股票交易所规定第 i 天的一次买入至多只能购买 ASi? 股,一次卖出至多只能卖出 BSi? 股. 另外,股票交

【SCOI2010】股票交易

Description [SCOI2010]股票交易 在T天时间内,第\(i\)天股票购入价为\(ap_i\),出售价为\(bp_i\),每天最多购入\(as_i\)股,最多出售\(bs_i\)股 任意时刻手中的股票数不能超过\(Maxp\),且两次交易至少间隔\(W\)天 最大化收益,初始资金视为无限大 Solution 单调队列+dp 根据题意不难设计状态,定义\(f[i][j]\)表示前\(i\)天,手里最后有\(j\)个股票的最大收益,那么状态转移方程就是: \[ f[i][j]= \b

BZOJ 1855 股票交易(单调队列优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每 个i,都有APi>=BPi),但是每天不能无限制地交易,于是股票交易所规定第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BS