题意:
t组输入,你有n个数,还有k个朋友,每一个朋友需要wi个数。意思就是你要给第i个朋友分配wi个数,输入保证w1+w2+...+wk=n
一个朋友的兴奋值是你分配给他的数中最大值加上最小值的和(如果某个朋友只有一个数,那最小值和最大值都是一样的)。
题解:
首先对于只需求一个数的朋友,我们应该先处理,给他分配最大的数给他,因为这样这些大数会被加两遍。
然后我们安排剩下的人。我们知道一个人的贡献只和最大值最小值有关,中间那些是什么并不关心,所以我们从拿的最多的那个人开始,因为当前剩下的数中,最小和最大的那两个数肯定是要被计算的,所以我们把这两个数给到这个人,中间的话我们考虑贪心,把剩下尽可能小的数尽可能给他。
代码:
#include <stdio.h> #include <string.h> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=2e5+10; #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); ll v[maxn],w[maxn]; int main() { ll t; scanf("%I64d",&t); while(t--) { ll n,k,ans=0; scanf("%I64d%I64d",&n,&k); for(ll i=0; i<n; ++i) { scanf("%I64d",&v[i]); } sort(v, v + n);//���� int t = n-1; for(ll i=0;i<k;++i) { scanf("%I64d",&w[i]); if(w[i]==1) { ans=ans+2*v[t]; //printf("%I64d*** ",ans); t--; } } // for(int i=0;i<k;++i) // { // // else // { // break; // } // } /* for (int i = 0; i < k; i++) { cin >> w[i]; if (w[i] == 1) { ans += v[t] * 2;//���Ϊ1������䵱ǰ����ֵ t--;//�������ֵ���±� } } */ sort(w, w + k);//���� //int y = k - temp; int l = 0; for (int i = k-1; i>=0; i--) //�ȷ���b[i]���ֵ��������ȥ������С��ֵ�� { if (w[i] != 1) { ans = ans + v[t] + v[l];//���ϵ�ǰ��С��ֵ�͵�ǰ����ֵ l = l + (w[i] - 1);//������Сֵ���±� t--;//�������ֵ���±� } } cout << ans << endl; /* for(ll i=0;i<k;++i) { scanf("%I64d",&w[i]); } sort(v,v+n); sort(w,w+k); ll sum=0; ll start=0,i,j; n--; for(i=0;i<k;++i) { if(w[i]==1) { sum=sum+2*v[n]; //printf("%I64d*** ",sum); n--; } else { break; } } for(j=k-1;j>=i;--j) { sum=sum+v[start]+v[n]; start+=(w[i]-1); n--; } printf("%I64d ",sum); */ } return 0; }