题意:给你n个盒子,最开始有一堆球,把对应数量的球放到盒子里。(简化版)计算分完所有球的penalty。操作方式是,先将一个非空盒子里的球全部倒出,然后将这堆球以你想要的方式放在2~3个盒子里。Penalty是你倒出球的数量。
WA代码:
#include<bits/stdc++.h>
using namespace std;
vector<int> a;
int main(){
int n;
long long ans=0;
cin>>n;
for(int i=1;i<=n;i++){
int num;
cin>>num;
a.push_back(num);
}
sort(a.begin(),a.end());
int power=1;
if(a.size()==1){
int c=a.back();
cout<<c<<endl;
return 0;
}
while(a.size()>=4){
int c;
c=a.back();
a.pop_back();
ans+=c*power;
c=a.back();
a.pop_back();
ans+=c*power;
power++;
}
if(a.size()==3){
for(int i=1;i<=3;i++){
int c=a.back();
a.pop_back();
ans+=c*power;
}
}
else{
for(int i=1;i<=2;i++){
int c=a.back();
a.pop_back();
ans+=c*power;
}
}
cout<<ans<<endl;
return 0;
}
分析:WA的思路就是正着分,从大到小一路分开。
但是这样会卡在一组样例上:
6
1 4 4 4 4 4
按照WA代码的思路,分出的顺序是4 4 4 4 4 1,ans=39,但是如果我们按照 4 9 8->4 1 4 4 8-> 4 1 4 4 4 4 的顺序分出的话,ans=38.
问题在于有没有正确理解题中的一句话:
The penalty of the turn is the number of balls Ivan takes from the box during the first step of the turn.
如果正确理解了这句话的话,显然要正着想这道题目是有难度的,要考虑多种情况,并不是简单的从大到小分开就可以解决的。
AC的思路是逆着题意,从分开的阶段一段一段地合成。那么一个优先队列轻松完成
AC代码:
#include<bits/stdc++.h>
using namespace std;
priority_queue<long long,vector<long long>,greater<long long> > a;
int main(){
int n;
long long ans=0;
cin>>n;
for(int i=1;i<=n;i++){
long long num;
cin>>num;
a.push(num);
}
if(!(n&1)){
a.push(0);
}
while((int)a.size()>1){
long long x,y,z;
x=a.top();
a.pop();
y=a.top();
a.pop();
z=a.top();
a.pop();
ans+=(x+y+z);
a.push(x+y+z);
}
cout<<ans<<endl;
return 0;
}