20190630 simulation game B (monotone queue optimization dp)

. dp undoubtedly a fact.

In the examination room, I wrote a wrong solution, but the data can be too small, but the space will burst, thinking about how to use the scroll array optimization to the examination room. . . . The equation wrong solutions listed come
`` `CPP
for (int I =. 1; I <= n-; I ++)
{
for (int J = 0; J <= K; J ++)
{
IF (! J = 0)
DP [i] [j] = max (dp [i-1] [j], dp [i-1] [j-1] + a [i]); // dp [i] [j] denotes the i-th former , the j-th selected or not selected, thereby obtaining this equation
the else
DP [I] [j] = ANS;
ANS = max (DP [I] [j], ANS);
}
}
`` `

Clearly the wrong. But also home to find positive solutions from the far off. I started to have thought of prefixes and, but do not know where something went wrong.

Summarizes the wrong reasons: space explode. Observation equation, in fact, apart from a small problem here: I obviously can add up to a whole paragraph, but with a single plus, which led to a burst of time and space.

Thus dp array transformation: or points before i, but j is transformed into the second break, the i-th point before dp j indicates when the maximum off equation:
dp [i] = max (dp [i] , dp [j-1] + a [j] + ... + a [i]);

dp similar prefix and a bar. The latter may be a long list of a [j] + ... + a [i] with the prefix and maintenance, it becomes
dp [i] = max (dp [i], dp [j-1] + sum [i ] -sum [j]);

So, dp inside a variable value and only about, so you can use (I and unskilled) monotonous queue for maintenance.

```cpp
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
int n,m;
int a[maxn];
int sum[maxn];
int dp[maxn];
int que[maxn];//队列下标
int d[maxn];//值
int h=0,t=1;

int main ()
{
Scanf ( "% D% D", & n-, & m);
for (int I =. 1; I <= n-; I ++)
{
Scanf ( "% D", & A [I]);
SUM [I ] = sum [i-1] + a [i]; // prefix and
}
for (int I =. 1; I <= n-; I ++)
{
D [I] DP = [-I. 1] -sum [I] ; // first, the value of the tail current value
while (h <= t && d [que [t]] <d [i]) t -; // this value is then compared with the previous value of the queue size, update the queue tail
que [++ t] = i; // new queue tail are when the subscript
while h ++ (h <= t && que [h] <im); // updates the header pointer holding head maximum
dp [i] = d [que [h ]] + sum [i]; // value
}
printf ( "% d", dp [the n-]);
return 0;
}
`` `
estimates say there are a lot of bad wrong, I am still a little ignorant of it, Gangster correct me hope.

(I hate dp)

Guess you like

Origin www.cnblogs.com/ajmddzp/p/11111986.html