拿物品(贪心)

拿物品(贪心)

链接:https://ac.nowcoder.com/acm/contest/3003/F
来源:牛客网

题目描述

牛牛和 牛可乐 面前有 n 个物品,这些物品编号为 1,2,…,n,每个物品有两个属性 ai,bi 。
牛牛与 牛可乐会轮流从剩下物品中任意拿走一个, 牛牛先选取。
设 牛牛选取的物品编号集合为 H,牛可乐选取的物品编号的集合为 T,取完之后,牛牛 得分为 i∈Hai;而 牛可乐得分为 i∈Tbi
牛牛和 牛可乐都希望自己的得分尽量比对方大(即最大化自己与对方得分的差)。
你需要求出两人都使用最优策略的情况下,最终分别会选择哪些物品,若有多种答案或输出顺序,输出任意一种。

输入描述:

第一行,一个正整数 n,表示物品个数。
第二行,n 个整数 a1,a2,…,an,表示 n 个物品的 A 属性。
第三行,n 个整数 b1,b2,…,bn,表示 n 个物品的 B 属性。
保证 2≤n≤2×1050≤ai,bi≤109

输出描述:

输出两行,分别表示在最优策略下 牛牛和 牛可乐各选择了哪些物品,输 出物品编号。

输入

3
8 7 6
5 4 2

输出

1 3
2

说明

3 1
2

也会被判定为正确

 

 

假设物品已经被选完,此时牛牛选择的物品 A 属性的价值和是 N , 牛可乐选择的物品 B 属性价值和是 M 。

如果 牛牛的 (a1,b1)物品与 牛可乐的 (a2,b2)交换,则 N′=N−a1+a2,M′=M+b1−b2,对于牛牛(目标是最大化 N−M )来说会变得更优仅当 a1+b1<a2+b2N′−M′>N−M 化简就能得到),对于牛可乐也一样。

所以两人都会优先选择 ai+bi最大的物品。

将物品按照两个属性的和从大到小排序,依次分给两人即可。

除排序时间复杂度 O(n) 。

 

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+7;
const int maxn=1e4+10;
using namespace std;

struct node
{
    int x,y;
    int pos;
}PT[200005];

vector<int> vt[2];//记录答案 

bool cmp(node a,node b)
{
    return a.x+a.y > b.x+b.y;
}

int main()
{
    #ifdef DEBUG
    freopen("sample.txt","r",stdin);
    #endif
    
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&PT[i].x);
        PT[i].pos=i;//记录位置 
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&PT[i].y);
    sort(PT+1,PT+1+n,cmp);
    for(int i=1;i<=n;i++)
        vt[i%2].push_back(PT[i].pos);
    for(int k=1;k>=0;k--)
    {
        for(int i=0;i<vt[k].size();i++)
            printf(i==vt[k].size()-1?"%d\n":"%d ",vt[k][i]);
    }
    
    return 0;
}

 

 

 

-

posted @ 2020-02-07 01:06  jiamian22  阅读(344)  评论(0编辑  收藏  举报