我觉得这道题出的很好 区别于“哈夫曼树”
因为事之多合并k个 理论说尽可能多合并。
然后我们看一个简单的例子
4 3
1 2 3 4 ——》6 4——》10 (6+10)=16;
1 2 3 4 ——》3 3 4---》 10 (3+10)=13;
除了保证合并树最小的数最底层 也要保证每个数的高度最低
1 #include <cstdio> 2 #include <algorithm> 3 #include <queue> 4 using namespace std; 5 typedef long long LL; 6 priority_queue <LL,vector <LL>, greater <LL> > q;//注意大整数 7 int n,k; 8 int main () 9 { 10 while (~scanf ("%d %d",&n,&k)) { 11 for (int i=1;i<=n;i++) { 12 LL x; scanf ("%lld",&x); 13 q.push(x); 14 } 15 int t=(n-1)/(k-1); 16 int p=n-(k-1)*t; 17 LL tmp=0; 18 for (int i=1;i<=p&&p!=1;i++) { 19 tmp+=q.top(); q.pop();// 先合并不足一次合并为k的 20 } 21 LL ans=tmp; 22 if (p!=1) q.push(tmp); 23 for (int i=1;i<=t;i++) { 24 tmp=0; 25 for (int j=1;j<=k;j++) { 26 tmp+=q.top(); q.pop(); 27 } 28 ans+=tmp; 29 q.push(tmp); 30 } 31 q.pop(); 32 printf ("%lld\n",ans); 33 } 34 return 0; 35 }
抓住青春的尾巴。。。