J-小朋友做游戏

题目描述

牛牛是一个幼儿园老师,他经常带小朋友们一起做游戏。

现在,牛牛的班里有AAA个安静的小朋友和BBB个闹腾的小朋友,牛牛想要从中选出恰好nnn个人来做游戏。这个游戏需要小朋友们手拉手围成一个圆圈,但不妙的是,如果两个闹腾的小朋友在圆圈中紧挨着,他们就会打闹,导致游戏无法进行。

每个小朋友还有一个幸福度v,若这位小朋友被选中参加游戏,则会使得班级的幸福度增加vvv。

请你求出,在满足上述所有限制的情况下,恰当的安排围成圆圈的方法,能使得班级的幸福度最大为多少。

输入描述:

输入第一行是一个整数T(1≤T≤1000),测试数据组数。

每组测试数据,第一行是三个整数A,B,n(2≤A,B≤104,3≤n≤A+B),含义如题目所示。

第二行是AAA个数,第iii个数vai(1≤vai≤10000)表示某位安静小朋友的幸福度。

第三行是BBB个数,第iii个数vbi(1≤vbi≤10000)表示某位闹腾小朋友的幸福度。

此外,保证所有测试数据的(A+B)(A+B)(A+B)之和不会超过2∗100000。

输出描述:

每组测试用例,输出一行一个整数,表示最大幸福度。若无论如何安排都不能进行游戏,输出−1-1−1。

这题言下之意就是闹腾的小朋友数量不超过n/2,比赛的时候我也确实是这样写的,但是我也不知道为啥错了

错误代码:

#include <bits/stdc++.h>

using namespace std ;
const int N = 2e5 + 8 ;
int a[N] , b[N] ; 
using ll = long long ; 
bool cmp(int x , int y) {
    return x > y ; 
}
ll solve(int x , int y) {
    ll sum = 0 ; 
    for(int i = 1 ; i <= x ; i ++) {
        sum += a[i] ; 
    }
    for(int i = 1 ; i <= y ; i ++) {
        sum += b[i] ; 
    }
    return sum ; 
}
int main(){
    int t  ;
    cin >> t ;
    while(t --) {
        int A , B , n ; 
        cin >> A >> B >> n ; 
        for(int i = 1 ; i <= A ; i ++){
            cin >> a[i] ; 
        }
        for(int i = 1 ; i <= B ; i ++) {
            cin >> b[i] ; 
        }
        if(n -A > A) cout << -1 << '\n' ; 
        else {
        sort(a + 1 , a + A + 1 , cmp ) ; 
        sort(b + 1 , b + B + 1 , cmp ) ; 
        int tmp = n / 2 ; 
        ll ans = -9999999 ; 
        
        for(int i = 1 ; i <= tmp ; i ++) {
            ll sum = solve(n - i , i) ; 
            ans = max(sum , ans ) ; 
        }
        ll sum = 0 ; 
        for(int i = 1 ; i <= n ; i ++) {
            sum += a[i] ; 
        }
        ans = max(sum , ans) ; 
        cout << ans << '\n' ; 
        }
    }
    
    return  0 ; 
}

AC代码:

#include <bits/stdc++.h>

using namespace std ;
const int N = 1e4 + 8 ;
int a[N] , b[N] ; 
using ll = long long ; 
bool cmp(int x , int y) {
    return x > y ; 
}
int main(){
    int t ; 
    cin >> t ; 
    while(t --) {
        int A , B , n ; 
        cin >> A >> B >> n ; 
        for(int i = 1 ; i <= A ; i ++) {
            cin >> a[i] ; 
        }
        for(int i = 1 ; i <= B ; i ++) {
            cin >> b[i] ; 
        }
        int maxb = min(n / 2 , B) ; 
        if(n - A > A ) cout << -1 << '\n' ; 
        else {
            sort(a + 1 , a + A + 1 , cmp) ;
            sort(b + 1 , b + B + 1 , cmp) ; 
            for(int i = 2 ; i <= A ; i ++) {
                a[i] = a[i] + a[i - 1] ; 
            }
            for(int i = 2 ; i <= B ; i ++) {
                b[i] = b[i] + b[i - 1] ; 
            }
            int ans = - 9999 ; 
            for(int i = 1 ; i <= A ; i ++) {
                int sol = n - i ; 
                if(sol > maxb || sol < 0) continue ; 
                ans = max(ans , a[i] + b[sol]) ; 
            }
            cout << ans << '\n' ; 
        }
    }
    
    return 0 ; 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值