堆+huffman树。
huffman二叉树构造法就是每次把最小的俩个合并起来,构成一个树。
但k叉树每回减少(k-1)个,可能最后会有一个坑位被浪费掉,导致答案增加(用心去感受)
于是我果断回忆去年他们游记里面写到,多余的先合并下。。
然后1A了。。。
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<vector> using namespace std; typedef long long LL; struct Point { LL x,b,res; bool operator < (const Point& rhs) const { return x>rhs.x || (x==rhs.x && b > rhs.b); } Point(LL a1=0,LL a2=0,LL a3=0) {x=a1; b=a2;res=a3;} }u[20]; priority_queue<Point,vector<Point> > q; LL n,k,tot,maxb,sum,a,c; int main() { scanf("%lld%lld",&n,&k); for(int i=1;i<=n;i++) { scanf("%lld",&a); q.push(Point(a,0)); } c=(n-1)%(k-1); if(c) { for(int i=1;i<=c+1;i++) { u[i]=q.top(); q.pop(); tot+=u[i].x; sum+=u[i].res; maxb=max(maxb,u[i].b); } q.push(Point(tot,maxb+1,sum+tot)); } while(q.size()>1) { tot=maxb=sum=0; for(int i=1;i<=k;i++) { u[i]=q.top(); q.pop(); tot+=u[i].x; sum+=u[i].res; maxb=max(maxb,u[i].b); } q.push(Point(tot,maxb+1,sum+tot)); } u[0]=q.top(); printf("%lld\n%lld\n",u[0].res,u[0].b); return 0; }
时间: 2024-10-13 14:03:04