AcWing 1087. Mowing the lawn [monotonous queue optimization DP] C++ detailed problem solution

Monotonic queue optimization DP


topic

After winning the best lawn competition in the town a year ago, FJ became lazy and never mowed the lawn again.

Now, a new round of the best turf competition has begun, and FJ hopes to win again.

However, FJ's lawn is very messy, so FJ can only let his cows do the job.

FJ has N cows in a row, numbered 1 to N.

The efficiency of each cow is different, and the efficiency of cow i is Ei.

The cows with adjacent numbers are very familiar. If FJ arranges more than K cows with consecutive numbers, these cows will strike to have a party.

Therefore, now FJ needs your help to find the most reasonable arrangement and calculate the maximum efficiency that FJ can get.

Note that the plan must not include more than K cows with consecutive numbers.

Input format
First line: two integers N and K separated by spaces;

Lines 2 to N+1: Line i+1 has an integer Ei.

The output format is
one line and contains a value indicating the maximum efficiency value that FJ can obtain.

Data range
1≤N≤105,
0≤Ei≤109
Input sample:
5 2
1
2
3
4
5
Output sample:
12
sample explanation
FJ has 5 cows with efficiencies of 1, 2, 3, 4 , and 5 .

FJ hopes that the total efficiency of the selected cows is the largest, but he cannot choose more than 2 consecutive cows.

Therefore, cows other than the third can be selected, and the total efficiency is 1 + 2 + 4 + 5 = 12.

Ideas

Analysis diagram
Insert picture description here

Status: It f[i] means ithe maximum efficiency value in the set of all legal schemes selected from the previous cow

State calculation:

For each cow i, there are two options: choose and not choose.

Do not choose the first icow f[i] = f[i-1],;

The first icow can be divided according to continuous length: length is 1, length is 2, length is 3, length isk

When we selected the continuous length of jtime (1<=j<=k), may be selected cattle
Insert picture description here
Note that the first i-jcow is not selected, because our cattle continuous length is selected j, the selected continuous length is greater than jthe.
So choose the first icow equation as:f[i]= f[i-j-1]+s[i]-s[i-j]

Convert ithe equation of the selected first cow
Insert picture description here

The state calculation equation is:f[i]=max(f[i-1],g[i-j]+s[i])

Consider optimization:

The maximum value depends on g[i-j], so define a kmonotonically decreasing queue maintenance g[i-j]with a length of , so that the head of the queue is the g[i-j]largest, and the head of the queue is taken out to update each time the answer is updated.

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL f[N];
LL s[N];
int q[N];  //数组模拟队列,队列中存放的是下标
LL g(int i)
{
    
    
    if(i==0)  return 0;
    return f[i-1]-s[i];
}
int main()
{
    
    
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%d",&s[i]);
        s[i]+=s[i-1];
    }
    int hh=0,tt=0;
    for(int i=1;i<=n;i++)
    {
    
    
       if(q[hh]<i-k) hh++;  //超出滑动窗口,出队列 ,此时s[i]还没入队,因此取不到等于号
       f[i]=max(f[i-1],g(q[hh])+s[i]);
       while(hh<=tt&&g(q[tt])<=g(i)) tt--;  //维护一个单调递减队列,队头元素最大
       q[++tt]=i;
    }
    printf("%lld\n",f[n]);
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45629285/article/details/111812377