列表

详情


NC25573. 序列操作Ⅰ

描述

一个长度为N的序列,所有元素均大于等于 ,你可以修改任意元素的值,使得修改之后所有元素的值仍均大于等于,且所有长度为k的区间的元素和均为负数,求最小的改动量之和。设一个元素改动后为,则这个元素的改动量为

输入描述

第一行包含三个正整数N,M,K,意义如题面所示。,
第二行包含N个整数a,描述这个序列的每一个元素大小

输出描述

输出一行一个整数表示答案。

示例1

输入:

4 5 2
7 5 8 10

输出:

32

说明:

可改为0 -1 0 -1,满足题目要求,且改动量之和为32

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 414ms, 内存消耗: 23524K, 提交时间: 2019-05-15 10:21:01

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[2000005];
int main()
{
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	int l = 1, cha = 0;
	ll sum = 0, ans = 0;
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	for (int i = 1; i <= k; i++)
		sum += a[i];
	for (int i = k; i >= 1; i--)
	{
		if (sum < 0)
			break;
		cha = min(sum + 1, (ll)m + a[i]);
		ans += cha;
		sum -= cha;
		a[i] -= cha;
	}
	for (int i = k + 1; i <= n; i++)
	{
		sum += a[i];
		sum -= a[l++];
		if (sum >= 0)
		{
			cha = sum + 1;
			ans += cha;
			sum -= cha;
			a[i] -= cha;
		}
	}
	printf("%lld", ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 402ms, 内存消耗: 23540K, 提交时间: 2019-05-18 14:37:01

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 2e6 + 100;
int a[maxn];

int main() {
	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
	}
	ll s = 0, ans = 0;
	for (int i = 0; i < k; ++i) {
		s += a[i];
	}
	for (int i = k; i <= n; ++i) {
		s += a[i] - a[i - k];
		for (int j = i; s >= 0 && j >= 1; --j) {
			ll mi = min(s + 1, 0LL + m + a[j]);
			a[j] -= mi, s -= mi, ans += mi;
		}
	}
	cout << ans << endl;
}

上一题