Codeforces Round #652 (Div. 2) C. RationalLee(思维,sort)

题目传送
题意:
给你n个整数(一些数可能为负),分给k个人(输入中给出每个人分多少个整数),现在每个人得到的价值为分给自己的整数中的最大值加上最小值。现在问所有人的获得的价值的最大值为多少?

思路:
我们先把n个整数和k个人所分的数量从小到大排个序。
1.现在我们要寻找这k个人中,有没有人只能得到一个整数,如果有的话,那么把最大的整数给他(因为他所能得到的价值是最大值的俩倍,所以最大的整数给他,对总体的价值肯定增长的越快)

2.把所有的只能得到一个数的人分配完了后,我们再排个序,使得剩下的人中分配的整数数量从大到小排序然后每次给分配数量最多的那一位分配一个目前的最大值,和一个目前的最小值,然后我们可以知道,其他的数对这个人的价值没有什么影响了,那么我们就疯狂的把现在所有的最小的数塞进去(让更大的数,有机会对其他人有价值)

AC代码

#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 3e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
bool cmp(ll a,ll b)
{
    return a > b;
}
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        ll n,k,num;
        cin >> n >> k;
        ll arr[n+5] = {0},ans[k+5] = {0},l = 1,r = n,sum = 0,q;
        for(int i = 1;i <= n;i++) cin >> arr[i];
        for(int i = 1;i <= k;i++) cin >> ans[i];
        sort(ans+1,ans+1+k);sort(arr+1,arr+n+1);//排序
        for(q = 1;q <= k;q++)
        {
            if(ans[q] != 1) break;//先把1的情况分配完
            sum += (arr[r]*2);
            r--;
        }
        if(q == k+1) cout << sum << endl;//如果全是1,那么就完了
        else
        {
            sort(ans+q,ans+1+k,cmp);//把剩下的数从大到小排序
            for(;q <= k;q++)
            {
                ans[q] -= 2;
                sum += (arr[r]+arr[l]);//给一个最大值和最小值
                r--,l++;
                while(ans[q]--) l++;//把剩下最小的数塞进去
            }
            cout << sum << endl;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值