junk-yao-blog

思路:
  状态:dp【i】【0】表示前i个元素,i号元素不取的情况,dp【i】【1】表示前i个元素,第i个取的情况。

  ·方程:dp【i】【1】=max【i-m <= j < i】(dp【j】【0】 - sum【j】) + sum【i】

     dp【i】【0】=max(dp【i-1】【0】, dp【i-1】【1】);

  优化:单调队列

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 200010;
inline int qread(){
    register int ch = getchar(), flag = 0, x = 0;
    while(ch < \'0\' || ch > \'9\')    {if(ch == \'-\') flag = 1; ch = getchar();}
    while(ch >= \'0\' && ch <= \'9\')    x = 10 * x + ch - 48, ch = getchar();
    return flag ? -x : x;
}
long long qu[maxn];
int head = 1, tail, pos[maxn];
long long sum[maxn];
long long data[maxn];
long long dp[maxn][2];
int n, m;
void dpmax(){
    for(int i = 1; i <= n; ++i){
        while(pos[head] < i - m + 1 && head <= tail)                        head++;
        while(qu[tail] <= dp[i - 1][0] - sum[i - 1] && head <= tail)        tail--;
        pos[++tail] = i;    qu[tail] = dp[i - 1][0] - sum[i - 1];
        dp[i][1] = qu[head] + sum[i];
        dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);    
    }
}
int main(void){
    n = qread(), m = qread();
    for(int i = 1; i <= n; ++i)
        data[i] = qread();
    for(int i = 1; i <= n; ++i)
        sum[i] = sum[i - 1] + data[i];    
    dpmax();
    cout << max(dp[n][0], dp[n][1]) << endl;    
    return 0;
}

 

分类:

技术点:

相关文章:

  • 2022-01-12
  • 2021-06-07
  • 2021-11-21
  • 2021-11-17
  • 2021-11-12
  • 2021-08-07
  • 2021-09-20
  • 2021-05-31
猜你喜欢
  • 2022-12-23
  • 2021-06-27
  • 2021-08-13
  • 2021-12-22
  • 2021-08-23
  • 2021-05-15
  • 2021-10-05
相关资源
相似解决方案