1836:【04NOIP提高组】合并果子(三种做法)

1836:【04NOIP提高组】合并果子(三种做法)_第1张图片


一,贪心

每次只要合并果子数量最小的两堆,再计算耗费的体力值即可。

代码:

#include 
using namespace std;
int ans,n,a[100001];
int main()
{
  cin>>n;
  for(int i = 0; i < n; i++) cin>>a[i];
  sort(a,a + n);
  while(n > 1)
  {
    a[1] += a[0];//合并最小的两堆
    ans += a[1];//消耗相应体力值
    for(int j = 1; j < n; j++) a[j - 1] = a[j];// 删除第一个元素
    n--;//长度--
    sort(a,a + n);//再次排序
  }
  cout<

 ,堆

每输入一个数就把它push进一个小顶堆,然后将最小的两个元素相加得到新的一堆(两个弹出操作),再消耗相应的体力值,再把新的一堆push进小顶堆中。

 代码:

#include 
using namespace std;
int ans,n,a[100001],sie = 0;//答案  输入果子种类的个数   长度
void push(int n)
{
  a[++sie] = n;
  push_heap(a + 1,a + 1 + sie,greater());//把n push进最小堆
}
int pop()
{
  pop_heap(a + 1,a + 1 + sie,greater());//弹出堆顶元素
  return a[sie--];//再返回堆顶数值
}
int main()
{
  cin>>n;
  for(int i = 1; i <= n; i++)
  {
    int t;
    cin>>t;
    push(t);//建立最小堆
  }
  while(sie > 1)
  {
    int s = pop() + pop();//将最小的两个元素相加得到新的一堆
    ans += s;//消耗相应的体力值
    push(s);//再把新的一堆push进小顶堆中
  }
  cout<

三,优先队列

#include 
using namespace std;
int ans,n,a[100001],sie = 0;
priority_queue,greater> q;
int main()
{
  cin>>n;
  for(int i = 1; i <= n; i++)
  {
    int t;
    cin>>t;
    q.push(t);
    sie++;
  }
  while(sie > 1)
  {
    int s = q.top();
    q.pop();
    s += q.top();
    q.pop();
    ans += s;
    q.push(s);
    sie--;
  }
  cout<

关于greater的用法,详见C++ std::greater用法及代码示例_诸葛灬孔暗的博客-CSDN博客_c++ greater 

你可能感兴趣的:(贪心算法,树,队列,算法,c++,开发语言)