Question address: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3401
Question meaning:
T-days, you can buy APIs, BPI, and ASI at most, and BSI at most every day.
A maximum of maxp items can be held, and two adjacent transactions must be larger than W days
Ask how much you can make at most at the end of day t
Solution:
There are three state transition equations, of which DP [I] [J] indicates the money I earned when J items exist on the day I.
DP [I] [J] = max (DP [I] [J], DP [I-1] [J]) // For the previous day I did nothing
There is a recurrence for buying
DP [I] [J] = max (DP [I] [J], max (DP [i-w-1] [k]-(J-k) * buyp [I])
Further split is DP [I] [J] = max (DP [I] [J], max (DP [i-w-1] [k] + K * buyp [I]) -J * buyp [I]);
0 <= (J-k) <= canbuyn [I]
We can use the priority queue to put the maximum I can see at the top of the team.
The same is true for selling, but the equation becomes
DP [I] [J] = max (DP [I] [J], max (DP [i-w-1] [k] + K * sellp [I]) -J * sellp [I]
0 <= (k-j) <= canselln [I]
BelowCode:
# Include <cstdio> # include <cstring> # include <iostream> # include <algorithm> # include <cmath> # include <cstdlib> using namespace STD; const int maxn = 3000; struct node {int Val, Pos;} Q [maxn]; int sellp [maxn], buyp [maxn]; int canselln [maxn], canbuyn [maxn]; int DP [maxn] [maxn]; int t, n, maxp, W; const int INF = 0x3f3f3f3f; void DPF () {for (INT I = 1; I <= N; I ++) {for (Int J = 0; j <= maxp; j ++) DP [I] [J] =-INF ;} // cannot be sold for the first W + 1 days. You can only buy for (INT I = 1; I <= N; I ++) {for (Int J = 0; j <= min (maxp, canbuyn [I]); j ++) {DP [I] [J] =-buyp [I] * J; // all purchases are negative accounts }}for (INT I = 2; I <= N; I ++) // For the previous day I did nothing {for (Int J = 0; j <= maxp; j ++) DP [I] [J] = max (DP [I] [J], DP [I-1] [J]);} For (INT I = W + 2; I <= N; I ++) // The first W + 1 days in addition to buy what can not be done, both can buy and can sell from W + 2 start {int pre = i-w-1; // for purchase, there is a recursive formula // DP [I] [J] = max (DP [I] [J], max (DP [i-w-1] [k]-(J-k) * buyp [I]) // further split is DP [I] [J] = max (DP [I] [J], max (DP [i-w-1] [k] + K * buyp [I]) -J * buyp [I]); // because it is bought, 0 <= (J-K) <= canbuyn [I] // we can use the priority queue to place the maximum I can see in the first int head, tail; head = 0; tail =-1; for (Int J = 0; j <= maxp; j ++) {DP [I] [J] = max (DP [I] [J], DP [I-1] [J]); node TMP; TMP. val = DP [pre] [J] + J * buyp [I]; TMP. pos = J; // insert it into the priority queue and go to the while (Head <= tail & Q [tail]. val <TMP. val) tail --; Q [++ tail] = TMP; // The first line must be 0 <= (J-K) <= canbuyn [I] While (Head <= tail & (J-Q [head]. pos)> canbuyn [I]) Head ++; // gets the first line if (Head <= tail) DP [I] [J] = max (DP [I] [J], Q [head]. val-J * buyp [I]);} // same for sales, but the equation becomes // DP [I] [J] = max (DP [I] [J], max (DP [i-w-1] [k] + K * sellp [I]) -J * sellp [I] // 0 <= (k-j) <= canselln [I] Head = 0; tail =-1; for (Int J = maxp; j> = 0; j --) {DP [I] [J] = max (DP [I] [J], DP [I-1] [J]); node TMP; TMP. val = DP [pre] [J] + J * sellp [I]; TMP. pos = J; while (Head <= tail & Q [tail]. val <TMP. val) tail --; Q [++ tail] = TMP; while (Head <= tail & (Q [head]. pos-j)> canselln [I]) Head ++; If (Head <= tail) DP [I] [J] = max (DP [I] [J], Q [head]. val-J * sellp [I]) ;}} int main () {scanf ("% d", & T); While (t --) {scanf ("% d", & N, & maxp, & W); For (INT I = 1; I <= N; I ++) scanf ("% d", & buyp [I], & sellp [I], & canbuyn [I], & canselln [I]); DPF (); int ans = 0; For (Int J = 0; j <= maxp; j ++) ans = max (ANS, DP [N] [J]); printf ("% d \ n", ANS);} return 0 ;}