Hdoj 3401 question connection
It tells you the purchase price of an item in T days, the maximum number of purchases and purchases on the day, and the maximum number of items saved in T days. Each purchase interval must be greater than W + 1
It is easy to think of DP [I] [J], indicating the maximum profit of saving J items at the end of day I
Initialize DP [I] [J] = DP [I-1] [J ];
Then the state equation DP [I] [J] = max (DP [k] [J]), where k <= I-w-1;
And DP [I] [J] = max (DP [k] [Z]-(J-z) * buyvalue [I]), where, k <= i-w-1, z <j and z> = J-maxbuy [I ];
DP [I] [J] = max (DP [k] [Z] + (Z-j) * sellvalue [I]), where k <= i-w-1, z> J and z <= J + maxcompute [I ];
So there will be an I, j, Z three-layer loop, and their range is 2000, so there is a complexity of 2000 ^ 3, and it must time out.
In this case, we can use the priority queue to optimize it to reduce the cycle.
When z <j and z> = J-maxbuy [I], DP [I] [J] = DP [k] [Z]-(J-Z) * buyvalue [I] = DP [k] [Z] + z * buyvalue [I]-J * buyvalue [I]
We can find that the DP [k] [Z] + z * buyvalue [I] is only related to Z;
-J * buyvalue [I]. The latter part is only related to J, and all Z values are the same;
So what we need is that the larger the value of the previous part of the formula, the better, and the Z range changes with the change of J, which is the usage of the priority queue.
Notes for this question
(1) is K can be set as i-w-1, because i-w-1 before all is not better than i-w-1, On the contrary i-w-1 this day may be better than the previous
(2) Don't forget I can come from I-1
(3) The final answer must be when there are 0 items remaining.
My code:
# Include <stdio. h>
// # Include <string. h>
// # Include <algorithm>
# Define cannot (-0x3fffffff)
# Deprecision Max 2100
Int DP [Max] [Max];
Int days [Max] [4];
Int que [Max], tail, front;
Int where [Max];
Int T, maxp, W;
Int max (int A, int B)
{
Return A> B? A: B;
}
Int main ()
{
Int I, J;
INT cases;
Int result;
Int xx;
Scanf ("% d", & cases );
While (cases --)
{
Result = 0;
Scanf ("% d", & T, & maxp, & W );
For (I = 1; I <= T; I ++)
{
Scanf ("% d", & days [I] [0], & days [I] [1], & days [I] [2], & days [I] [3]);
}
For (I = 1; I <= T; I ++)
{
If (I <= W + 1)
{
For (j = 0; j <= maxp; j ++)
{
If (j <= days [I] [2])
{
DP [I] [J] =-J * Days [I] [0];
}
Else
{
DP [I] [J] = cannot;
}
If (I> 1)
DP [I] [J] = max (DP [I] [J], DP [I-1] [J]);
}
}
Else
{
For (j = 0; j <= maxp; j ++)
{
DP [I] [J] = DP [I-w-1] [J];
DP [I] [J] = max (DP [I] [J], DP [I-1] [J]);
}
Tail =-1;
Front = 0;
Int temp = 0;
For (j = 0; j <= maxp; j ++)
{
While (temp <j)
{
If (DP [I-w-1] [temp] = cannot)
{
Temp ++;
Continue;
}
Xx = DP [I-w-1] [temp] + temp * Days [I] [0];
While (front <= tail)
{
If (XX> = que [tail])
Tail --;
Else
Break;
}
Que [++ tail] = xx;
Where [tail] = temp;
Temp ++;
}
While (front <= tail & J-where [Front]> days [I] [2])
{
Front ++;
}
If (front <= tail)
DP [I] [J] = max (DP [I] [J], que [Front]-J * Days [I] [0]);
}
Tail =-1;
Front = 0;
Temp = 0;
For (j = 0; j <= maxp; j ++)
{
While (temp <= J + days [I] [3] & temp <= maxp)
{
If (DP [I-w-1] [temp] = cannot | temp <= J)
{
Temp ++;
Continue;
}
Xx = DP [I-w-1] [temp] + temp * Days [I] [1];
While (front <= tail)
{
If (XX> = que [tail])
Tail --;
Else
Break;
}
Que [++ tail] = xx;
Where [tail] = temp;
Temp ++;
}
While (front <= tail & where [Front] <= J)
{
Front ++;
}
If (front <= tail)
DP [I] [J] = max (DP [I] [J], que [Front]-J * Days [I] [1]);
}
}
}
// Result = 0;
// For (I = 0; I <= maxp; I ++)
// Result = max (result, DP [T] [I]);
// Printf ("% d \ n", result );
Printf ("% d \ n", DP [T] [0]);
}
Return 0;
}