問題描述:在一個操場的四周擺放着n堆石子,現要将石子有次序地合并成一堆。規定每次至少選2堆至多選k堆石子合并成新的一堆,
合并的費用為新的一堆石子數。計算出将n堆石子合并成一堆的最大總費用和最小總費用。
算法設計:對于給定的n堆石子,計算合并成一堆的最大總費用和最小總費用。
資料輸入:檔案的第1行有2個正整數n和k,表示有n堆石子,每次至少選2堆至多選k堆石子合并。第2行有n個數,分别表示每堆石子的個數。
輸入示例:
7 3
45 13 12 16 9 5 22
輸出示例:
593 199
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int i,stone[999];
int stonemax(int n,int k)
{
priority_queue<int> q;
//生成最大優先隊列
for(i=0;i<n;i++)
q.push(stone[i]);
int sum=0,max=0;
while(q.size()>2)
//因為要求最大總費用,是以要求合并次數盡量多
{
sum=0;
for(i=0;i<2;i++)
{
sum+=q.top();
q.pop();
}
max+=sum;
q.push(sum);
}
while(!q.empty())
{
max+=q.top();
q.pop();
}
return max;
}
int stonemin(int n,int k)
{
priority_queue<int,vector<int>,greater<int> > q;
//生成最小優先隊列
for(i=0;i<n;i++)
q.push(stone[i]);
int sum=0,min=0;
while(q.size()>k)
//因為要求最小總費用,是以要求合并次數盡量少
{
sum=0;
for(i=0;i<k;i++)
{
sum+=q.top();
q.pop();
}
min+=sum;
q.push(sum);
}
while(!q.empty())
{
min+=q.top();
q.pop();
}
return min;
}
int main()
{
int n,k;
cin>>n>>k;
for(i=0; i<n; i++)
cin>>stone[i];
cout<<stonemax(n,k)<<endl;
cout<<stonemin(n,k)<<endl;
return 0;
}
運作截圖:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CXuVzVZ9GczIGasdkYsRmMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DN0QzNwkTM5ETMzUDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)