A Daily Topic # 2 最大的和(前缀和/双指针)

A Daily Topic # 2

最大的和

给定一个长度为 n 的正整数数列 a1,a2,…,an。

初始时,数列中的每个元素要么处于可选状态,要么处于不可选状态。

你可以选择一个长度恰好为 k 的区间 [i, i + k - 1],使得 这 k 个元素的状态全部变为可选。

请问,在经过此操作后,所有处于可选状态的元素之和最大是多少。

输入格式

第一行包含两个整数 n 和 k。

第二行包含 n 个整数 ai。

第三行包含一个长度为 n 的 01 序列,如果第 i 个数为 11,表示 ai 的初始状态为可选,如果第 i 个数为 0,表示 ai 的初始状态为不可选。

输出格式

一行一个整数,表示答案。

数据范围

对于 30% 的数据,1≤k≤n≤1000
对于 100% 的数据,1≤k≤n≤1e5,1≤ai≤1e5

输入样例1:

3 1
2 5 4
0 0 1

输出样例1:

9

输入样例2:

4 3
10 5 4 7
0 1 1 0

输出样例2:

19

+++

思路:1.前缀和 2.双指针

//前缀和code
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 1e5 + 10;

LL s[N];
int n, k;
int a[N], b[N];
LL ans;

int main()
{
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &b[i]);
    for (int i = 1; i <= n; i ++ )
    {
        scanf("%d", &a[i]);
        if (a[i]) ans += b[i];
    }
    
    for (int i = 1; i <= n; i ++ )
    {
        s[i] = s[i - 1];
        if (!a[i]) s[i] += b[i]; 
    }
    
    LL res = 0;
    for (int i = 1; i + k <= n; i ++ )
        res = max(res, s[i + k - 1] - s[i - 1]);
    
    printf("%lld
", ans + res);
    
    return 0;
}

2.双指针

原文地址:https://www.cnblogs.com/scl0725/p/14757059.html