求助站外题(RE)
  • 板块学术版
  • 楼主jjl_cxk
  • 当前回复20
  • 已保存回复20
  • 发布时间2023/7/14 20:17
  • 上次更新2023/11/3 09:49:30
查看原帖
求助站外题(RE)
1000828
jjl_cxk楼主2023/7/14 20:17

说明 山谷中住着一个巨大的蚂蚁王国,蚁穴外有一个整洁的广场,天气晴好时蚁群常在那里举行各种活动。这天夜里,天降果子尘,第2天,广场上堆满了大大小小的果子堆,蚁哨出去数了数共有n堆,蚁后要求她的臣民将广场上的果子堆清理掉。具体办法是:每次可以把广场上的任意k堆果子合并成一堆,重复进行直至所有的果子堆最终合并成一堆。规定 (1):2≤k≤m,m由蚁后指定, (2):每次合并k堆果子的代价是这k堆果子子的重量和。

你的任务是,对给定的n和m,计算出将n堆果子最终合并成1堆的最小总代价。

例如,广场上有7堆果子,其重量分别为45,13,12,16,9,5,22。当m=3时,这些果子堆合并成一堆的最小总代价为199。当m=5时,这些果子堆合并成一堆的最小总代价为148。

输入格式

包含n+2个整数(n≤100000),其中第一行2个正整数,分别表示n堆果子和每次合并时可以合并的最大堆数m,从第二行开始有n个数,表示n堆果子的重量(1~500),数与数之间用空格隔开。

输出格式

只包含一个正整数,表示将n堆果子合并成1堆所需的最小总代价。

样例

输入数据 1

7 3

45 13 12 16 9 5 22

输出数据 1

199

我的代码

#include<bits/stdc++.h>//完全m叉树 
#define int long long//为什么Runtime Error Segmentation fault(失去理智)
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;
int n,m,k,t,sum,s,c;
long long ans=0;
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)	cin>>k,q.push(k);
	while(n<=m)//这里看需要补几个0构造 
	{
		c=n/m;
		s=n%m;
		n=c+s;
	}
	sum=m-n;
	for(int i=1;i<=sum;i++)//补0
		q.push(0);
	while(true)
	{
		t=0;
		for(int i=1;i<=m;i++)//选择m个小值 
		{
			t=t+q.top();
			q.pop();
		}
		ans=ans+t;
		if(q.empty()==true)//判断堆是否为空如果空就说明搬完了 
		{
			cout<<ans;
			return 0;
		}
		q.push(t);//把m堆堆好的果子继续放到堆里 
	}
	return 0;
} 
2023/7/14 20:17
加载中...