UPC——排队(前缀和)

该博客介绍了如何利用前缀和技巧解决一道算法题,题目涉及计算队伍中连续子序列的最小违和值。博主通过分析样例输入和输出,展示了如何高效地找到使违和值最小的连续子序列,避免了暴力求解导致的时间复杂度过高。解题思路是计算每个人与前后人的身高差作为违和度,并累加得到前缀和,然后遍历所有可能的连续子序列,找出违和度之和最小的情况。
摘要由CSDN通过智能技术生成

题目描述

洛洛在外出旅游的时候发现社会上文明的现象越来越多,人们在买票的时候都会自发地排队等候。
遗憾的是排队的人身高参差不齐,有时候前后两人之间的身高相差太大,缺乏一些美感。
如果把前后两人的身高差(差值为正数)表示为两者前后相邻时产生的违和度,一段连续的人群因为前后两人身高不同而产生的违和度之和就可以被称为违和值。洛洛希望知道在队伍哪一段,且该段队伍由连续的m个人组成,其违和值最小。

输入

第一行输入两个正整数 n,m,n表示队伍的总人数,m表示某一段的人数。
第二行输入n个整数,表示队伍中n个人的身高(单位:厘米)。

输出

输出包含一个整数,即最小的违和值。

样例输入 Copy

样例输入1
4 3
1 2 4 7

样例输入2
4 3
10 7 5 4

样例输出 Copy

样例输出1
3

样例输出2
3

提示

样例2说明:m=3,要选取3个连续的人有两种选法:
10 7 5: 违和度之和=3+2=5
7 5 4: 违和度之和=2+1=3
所以答案是3。

对于50%的数据保证2 ≤ n ≤ 10;
对于80%的数据保证2 ≤ n ≤ 1000;
对于100%的数据保证2 ≤ n ≤ 100000,1 ≤ m < n,每个人的身高不超过300厘米。

 解题思路:此题就是用前缀和来求区间元素的和, 如果暴力肯定会超时。

Code:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <iomanip>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

typedef long long LL;

typedef int Status;

const int N = 1e5 + 30;

LL n, x, y, z, m, tt = -1, hh, k, minn = 999999999, ans;
int q[N], a[N], b[N], s[N];

signed main()
{
	cin >> n >> m;
	y = m - 1;
	for(int i = 1; i <= n; i ++ )  scanf("%d", &a[i]);
	for(int i = 1; i <= n - 1; i ++ )  b[i] = fabs(a[i + 1] - a[i]);
	for(int i = 1; i <= n - 1; i ++ )  s[i] = s[i - 1] + b[i]; //前缀和
	for(int i = 1; i <= n - y; i ++ )
	{
		ans = fabs(s[i + y - 1] - s[i - 1]);
		minn = min(ans, minn);
	}
	cout << minn << endl;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值