#include <iostream>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<math.h>
#include <algorithm>
#include<cstdlib>
#include<vector>
int nums1[201];
int nums2[201];
int getMax(int n) {
// 排序
sort(nums1,nums1+n);
// 从后往前
int i = n - 1;
// 代价
int cost = 0;
// 当还剩不止1堆时
while (i-1>=0) {
// 合并i与i-1位置,合并到i-1位置
nums1[i - 1] += nums1[i];
// 代价+这两堆
cost += nums1[i - 1];
// 继续往左走
i--;
}
//合并完返回代价
return cost;
}
int getMin(int n,int k) {
// 保证最后一次也合并k堆,添加前置0
while (n % (k-1) != 1) {
nums2[n] = 0;
n++;
}
// 起始为0
int start = 0;
// 代价
int cost = 0;
// 先排序整个数组
sort(nums2 , nums2 + n);
// n-1是我们最后一个位置,当start还没到n-1时
while (start < n-1) {
// 合并[start~ start+k-1)到start+k-1的位置
// 也就是合并最小这k个
for (int i =start ;i < start + k - 1;i++) {
nums2[start + k - 1] += nums2[i];
}
// 代价
cost += nums2[start + k - 1];
// 然后从nums2+ start + k - 1到n开始排序
sort(nums2+ start + k - 1, nums2 + n);
// 继续往右走合并下一组k个
start = start + k - 1;
}
// 返回代价
return cost;
}
int main()
{
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> nums1[i];
nums2[i] = nums1[i];
}
cout << getMin(n,k) << ' ' << getMax(n) << endl;
return 0;
}
11079 可以移动的石子合并(优先做)
最新推荐文章于 2022-11-21 20:06:29 发布