【JZOJ 100029】【NOIP2017提高A组模拟7.8】陪审团 (贪心+排序)

问题描述
陪审团制度历来是司法研究中的一个热议话题,由于陪审团的成员组成会对案件最终的结果产生巨大的影响,诉讼双方往往围绕陪审团由哪些人组成这一议题激烈争夺。 小 W 提出了一个甲乙双方互相制衡的陪审团成员挑选方法:假设共有 n 名候选陪审团成员,则由甲先提名 s 位候选人,再由乙在甲提名的 s 位候选人中选出 t 名,作为最终的陪审团成员。显然这里应当有n ≥ s ≥ t。假设候选人 k 对甲、乙的有利程度都可以用一个二元组(����, ����)来表示,����越大说明候选人 k 对甲越有利,����越大则对乙越有利。在此前提下,双方的目标都变得明确:甲要最大化最终陪审团 t 人的 x 之和,最小化 y之和,乙则反之。 现在甲方决定聘请你为律师,并且事先得知了乙方律师的策略:乙方律师会在你提名的 s 名候选人中选出 t 名使得这 t 人的 y 值之和最大,再保证 y 值之和最大的前提下使得 x 值之和尽量小(在对乙方最有利的前提下对甲方最不利)。 现在你应当慎重地提名 s 位候选人使得最终由乙方律师确定的 t 人 x 值和最大,若有多种方案,则应再使被乙方排除掉的 s-t人的 y 值和尽量大,在此基础上最大化 s 人的 x 值 之和,在此基础上最小化 s 人的 y 值 之和。 你的当事人并不关心你提名的具体是哪些人,只要你告诉他你提名的 s 人的 x 值之和 与 y 值之和。
输入
第一行包含三个整数 n,s,t。 接下来 n 行,每行两个整数分别表示xk, yk。
输出
共一行两个整数,分别为 x 值之和与 y 值之和。
样例输入
3 2 1
2 1
3 4
5 2
样例输出
7 3
数据范围
对于 30%的测试数据n ≤ 20
对于 50%的测试数据n ≤ 100
对于 100%的测试数据n ≤ 100000, x, y ≤ 1000000
算法讨论
显然我们要先选出对自己最有利的t个人,然后我们要做到让乙方律师只能选对我们最有利的t个,那么我们剩下的s-t个人的y就要小于t个人中最小的y,排多几次序后选人就好。

#include <cstdio>
#include <algorithm>
#define MAX_N 1000006
using namespace std;
struct arr
{
    int x,y,m;
}a[MAX_N];
int n,s,t,Min=0x7f7f7f7f;
long long x,y;

bool cmp(arr a,arr b)
{
    if (a.x==b.x)
        return a.y>b.y;
    return a.x>b.x;
}

bool cmp1(arr a,arr b)
{
    if (a.y==b.y)
        return a.x<b.x;
    return a.y<b.y;
}

int main()
{
    scanf("%d%d%d",&n,&s,&t);
    for (int i=1;i<=n;i++)
        scanf("%d%d",&a[i].x,&a[i].y);
    sort(a+1,a+n+1,cmp1);
    for (int i=1;i<=n;i++)
        a[i].m=i;
    sort(a+s-t+1,a+n+1,cmp);
    for (int i=s-t+1;i<=s;i++)
    {
        x+=a[i].x;
        y+=a[i].y;
        if (a[i].m<Min)
            Min=a[i].m;
    }
    sort(a+1,a+n+1,cmp1);
    for (int i=Min-1;i>=Min-s+t;i--)
    {
        x+=a[i].x;
        y+=a[i].y;
    }
    printf("%lld %lld",x,y);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值