Description
有n堆石子形成一行(a1,a2,…,an,ai为第i堆石子个数),现要将石子合并成一堆,规定每次可
选择至少2堆最多k堆移出然后合并,每次合并的分值为新堆的石子数。若干次合并后,石子最后肯定被合并为一堆,得分为每次合并的分值之和。
现在求解将这n堆石子合并成一堆的最低得分和最高得分。
输入格式
两行。第一行n和k。
第二行a1 a2 … an,每个ai(1<=i<=n)表示第i堆石子的个数,n<=200,2<=k<=n。
输出格式
仅一行,为石子合并的最低得分和最高得分,中间空格相连。
输入样例
7 3 45 13 12 16 9 5 22输出样例
199 593
代码
#include <iostream>
#include <algorithm>
using namespace std;
int a[222];
int b[222];
int MaxSum = 0;
int MinSum = 0;
int n, k;
void Pmax() {
for (int i = n-1; i >0; i--)
{
b[i - 1] += b[i];
MaxSum += b[i- 1];
}
}
void Pmin() {
for (int i = n-1; i >0; i= i - k + 1)
{
for (int j = 0; j < k-1; j++)
{
a[i - k + 1] += a[i - j];
}
MinSum += a[i - k + 1];
sort(a, a+ i - k + 2, greater<int>());
}
}
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> a[i];
b[i] = a[i];
}
sort(b, b + n);
Pmax();
while ((n % (k - 1)) != 1) {
a[n] = 0;
n += 1;
}
//n++;
sort(a, a + n, greater<int>());
Pmin();
cout << MinSum << " " << MaxSum;
return 0;
}