【思维题】Codeforce 1197C Array Splitting

这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!

一、题目大意

题目的大致意思就是,给定一个长度为n的不减数组,即后一个元素大于等于前一个元素,然后要求把这个数组分为k个非空连续子数组,定义每种切分的方法代价为这k个子数组最大值减最小值的和,用公式表示即:
在这里插入图片描述
其中,max(i)和min(i)分别表示第i个子数组中的最大值和最小值。求使代价最小的切分方法。

二、题目思路以及AC代码

本来这道题也想写水题的,但后来想想,都写水题之后也不好区分,就写成思维题了。

这题的关键就是找寻一种合理的切分方法。这里我提供一种思路,就以题目中的第一个样例为例。
在这里插入图片描述
输入的数组为4 8 15 16 23 42,那么由于要求差,我们不妨再开一个数组用于保存其相邻两个数的差,即diff数组,其内容是4 7 1 7 19,然后题目要求我们切分数组,那么切分完之后,会对结果有什么影响呢?比如我们现在在8和15中间切了一下,那么结果就是4+1+7+19,如果再在23和42之间切一刀,那结果就是4+1+7,可以发现,我们的切分无非是在去除diff中的某些值,那么结果要求和最小,那么也就是说,只要把diff中最大的k-1个值去除掉就好了(k-1的原因是要分成k组,则要切k-1刀)。

下面给出AC代码:

#include <iostream>
#include <algorithm>
#define MAXN 300010
using namespace std;

int n, k;
int a[MAXN];
int diff[MAXN];

bool cmp(int a, int b) {
	return a > b;
}

int main()
{
	cin >> n >> k;

	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}

	for (int i = 1; i < n; i++) {
		diff[i] = a[i + 1] - a[i];
	}

	sort(diff + 1, diff + n, cmp);

	int ans = 0;
	for (int i = k; i < n; i++) {
		ans += diff[i];
	}

	cout << ans << endl;

    return 0;
}

如果有问题,欢迎大家指正!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值