問題の説明:遊び場の周りにn個の石の山があります。これで、石は整然と1つの山にまとめられます。毎回2本以上k本以下の石を選び、組み合わせて新しい山にすることを定めており、組み合わせの費用は新しい石の山の数です。n個の石の山を1つの山に結合する場合の最大総コストと最小総コストを計算します。
アルゴリズムの設計:与えられたn個の石の山について、最大の総コストと最小の総コストを1つの山にまとめて計算します。
データ入力:ファイルの最初の行に2つの正の整数nとkがあります。これは、n個の石の山があり、毎回少なくとも2つの山、最大でk個の石の山が選択されることを意味します。2列目にはn個の数字があり、各山の石の数を表しています。
入力例:
7 3
45 13 12 16 9 5 22
出力例:
593 199
アイデア:最大の杭を使用して、一度に2つの最大の杭を選択します。合計が、最大コストです。最小ヒープを使用して、毎回kの最小ヒープを選択すると、合計が最小になります。(なぜだか分からない)
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int main()
{
int n, k;
while (cin >> n >> k)
{
vector<int>v;
v.push_back(0);
priority_queue<int, vector<int>, less<int>>p;
priority_queue<int, vector<int>, greater<int>>q;
for (int i = 1; i <=n; i++)
{
int num;
cin >> num;
v.push_back(num);
p.push(num);
q.push(num);
}
int max_sum=0, top;
while (p.size() > 1)
{
top = p.top();
p.pop();
top+=p.top();
p.pop();
max_sum += top;
p.push(top);
}
int min_sum = 0;
while (q.size() > k)
{
top = 0;
for (int i = 0; i < k; i++)
{
top += q.top();
q.pop();
}
q.push(top);
min_sum += top;
}
while (q.size())
{
top = q.top();
min_sum += top;
q.pop();
}
cout << "maxs_sum: " << max_sum << "min_sum: " << min_sum << endl;
}
return 0;
}
/*
7 3
45 13 12 16 9 5 22
*/