ACWing夏季每日一题打卡day —— AcWing 3493. 最大的和

Posted Johnny*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACWing夏季每日一题打卡day —— AcWing 3493. 最大的和相关的知识,希望对你有一定的参考价值。

AcWing 3493. 最大的和

【题目描述】

在这里插入图片描述

AcWing 3493. 最大的和

【思路】

使用两次前缀和

import java.io.*;
public class Main{
    static int N = 100010;
    static int a[] = new int[N];
    static int selected[] = new int[N];
    
    static long s[] = new long[N];  //前缀和
    static long selectedS[] = new long[N];  //选择状态下的和
    
    public static void main(String agrs[]) throws Exception{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str[] = bf.readLine().split(" ");
        int n = Integer.parseInt(str[0]), k = Integer.parseInt(str[1]);
        String data[] = bf.readLine().split(" ");
        String status[] = bf.readLine().split(" ");
        
        for(int i = 1; i <= n; i ++){
            a[i] = Integer.parseInt(data[i - 1]);
            selected[i] = Integer.parseInt(status[i - 1] );
            
            s[i] = s[i - 1] + a[i];
            selectedS[i] = selectedS[i - 1] +  (selected[i] == 1? a[i] : 0 );
            
        }
        
        
        long ans = 0;
        //枚举区间左端点
        for(int i = 1; i + k <= n; i ++){
            int j = i + k - 1;
            //selectedS[i - 1]: a[ :i - 1]
            //s[j] - s[i - 1]: a[i:j]
            //selectedS[n] - selectedS[j] :  a[ j + 1 : n]
            long t = s[j] - s[i - 1] + selectedS[i - 1] + selectedS[n] - selectedS[j];
            if( t > ans ) ans = t;
        }
        System.out.println(ans);
        
            
        
    }
}

解法二: 双指针

【思路】
在这里插入图片描述

序列的和可以分为两部分:S初始可选 + S新可选(来自于不可选)
s维护滑动窗口中所有可选元素的和

import java.util.Scanner;
public class Main{
    static int N = 100010;
    static int a[] = new int[N];
    static int b[] = new int[N];
    
    public static void main(String agrs[]){
        Scanner reader = new Scanner(System.in);
        int n = reader.nextInt(), k = reader.nextInt();
        for(int i = 0; i < n; i ++) a[i] =reader.nextInt();
        for(int i = 0; i < n; i ++) b[i] =reader.nextInt();
        
        long sum = 0;
        for(int i = 0; i < n; i ++)
            if( b[i] == 1) sum += a[i];
        
        long s = 0, max = 0;
        for(int i = 0; i < n; i ++){
            
            //新增可选
            if(b[i] == 0) s += a[i];
            // a[i- k]元素滑出窗口 
            if( i >= k && b[i - k] == 0 ) s -= a[i - k];
            max = Math.max(s, max);
        }
        System.out.println(sum + max);
        
    }
}

以上是关于ACWing夏季每日一题打卡day —— AcWing 3493. 最大的和的主要内容,如果未能解决你的问题,请参考以下文章

夏季每日一题打卡day5——AcWing 3489. 星期几

夏季每日一题打卡day3 —— AcWing 3499. 序列最大收益

夏季每日一题打卡day1 —— AcWing 3485. 最大异或和

春季每日一题打卡day2 —— AcWing 435. 传球游戏

解题报告Acwing每日一题 夏季 [1/16]

AcWing夏季每日一题--最长公共子序列