题目
输入样例和输出样例
分析输入,n为数列的长度,也即数据的个数;k为选取的区间,也即可选状态;
a
i
a_i
ai为具体数据的内容。每个数据对应一个状态,0或者1,如果数据在区间里面,可以从0变到1。
代码实现
#AcWing 3493. 最大的和
# 滑动指针,不用开数组记录前缀和
# 思路 求和:ans:标签为1的和+delta_res:改变标签为1的和
# 求标签为1的和
def sum_1(arr, bos):
ans = 0 # 求和,求标签为1的和
for a, b in zip(arr, bos): # 打包为元组的列表,元素个数与最短的列表一致
ans = ans + a * b
return ans
# 求前k个区间的标签为0的和,和下面进行对比,选取最大值
def delta_k(k):
delta = 0
for i in range(k):
delta = delta + arr[i] * (1 - bos[i])
#delta_res = delta
return delta
# k区间,改变标签为1的和,比较,选取最大值
def delta_change(arr,k):
delta_res,delta=delta_k(k),delta_k(k)
l, r = 0, k
while r < n: # k小于n,区间长度小于数字长度
#delta=0 #归零
inc = arr[r] * (1 - bos[r]) - arr[l] * (1 - bos[l])
#print("inc:",inc)
delta = delta + inc
l = l + 1
r = r + 1
if inc > 0:
delta_res = max(delta_res, delta)
# elif delta_res ==0: #处理前k区间刚好是最大的情况
#delta_res = delta_k(k)
return delta_res
if __name__ == "__main__":
# 输入
n, k = map(int, input().split()) # n为数组长度,k为选取区间长度
arr = list(map(int, input().split())) # n个数,存储在arr中
bos = list(map(int, input().split())) # 1 or 0 ,可以考虑用字典储存
# 输出
# print("1:",sum_1(arr,bos))
#print("2:",delta_change(arr,k))
#print("3:",delta_k(k))
print(sum_1(arr,bos) + delta_change(arr,k))
代码待优化
其他参考代码
n, k = map(int, input().split())
nums = list(map(int, input().split())) # 原数组
freq = list(map(int, input().split())) # 初始可选状态数组
s = 0 # 当前滑动窗口内初始不可选的数字总和
cnt = 0 # 滑动窗口内初始不可选的数字总和的历史最大值
opt = 0 # 原数组内初始可选数字的总和
left, right = 0, 0 # 滑动窗口左右边界
while right < n:
if freq[right] == 1: # 判断右边界的数字初始是否可选
opt += nums[right]
else:
s += nums[right]
if right - left + 1 >= k: # 窗口滑动
cnt = max(cnt, s)
if freq[left] == 0: # 移动左侧窗口
s -= nums[left]
left += 1
right += 1
print(cnt + opt)
n,k=map(int,input().split())
arr=list(map(int,input().split()))
bin=list(map(int,input().split()))
S=0
# 累加状态为1的数
for i in range(n):
if bin[i]:
S+=arr[i]
res=0
pre=0
# 滑动窗口计算长度为k的区间状态为0对应数值的和
for i in range(n):
if bin[i]==0:
pre+=arr[i]
res=max(res,pre+S)
if i>=k-1 and bin[i-k+1]==0:
pre-=arr[i-k+1]
print(res)
作者:追风少年666
链接:https://www.acwing.com/activity/content/code/content/1222584/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
C代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n, m;
int a[N], b[N];
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
for (int i = 0; i < n; i ++ ) scanf("%d", &b[i]);
LL sum = 0;
for (int i = 0; i < n; i ++ )
if (b[i])
sum += a[i];
LL v = 0, s = 0;
for (int i = 0; i < n; i ++ )
{
if (!b[i]) s += a[i];
if (i >= m && !b[i - m]) s -= a[i - m];
v = max(v, s);
}
printf("%lld\n", sum + v);
return 0;
}