题解 P6002 【[USACO20JAN]Berry Picking S】

· · 题解

思路

$\qquad$详情见代码。 ## 代码 ``` #include<bits/stdc++.h>//万能头 #define ll long long using namespace std; int n,k,a[5001],l,ans;//ans表示答案 priority_queue<int>q,kong;//利用优先队列取最优,kong用来快速清空。 void doit(int x){//x表示一个篮子最多的果子数 q=kong; l=0; for(int i=1;i<=n;i++){ l+=a[i]/x;//按这种装法可以装满多少篮子 q.push(a[i]%x);//余下来的直接加入优先队列 } } void kk(int x){ int w;//w记录在一个篮子最多装x个的情况下贝茜可以得多少个 w=(l-(k/2))*x;//剩下来的篮子给bessie for(int i=1;i<=k-l;i++){ w+=q.top();//取剩下最多的补完k个篮. q.pop(); }//也可以直接存到数组里然后sort排序后再取. if(ans<w)ans=w; } int main () { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } sort(a+1,a+1+n); for(int i=a[n];i>=a[1];i--){ doit(i); if(l>=k){//如果有一个可以取到,那么低的必然能取到,答案也不会更优,所以直接退出。 if(ans<k*i/2)ans=k*i/2; break; }else if(l<k/2)continue;//取不到直接跳过(也就是说bessie的妹妹不可能最小的一个篮子是i个) else kk(i); } printf("%d",ans);//输出 return 0; } ```