zoukankan      html  css  js  c++  java
  • 拿物品(贪心)

    链接: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) 。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e4+10;
    17 using namespace std;
    18 
    19 struct node
    20 {
    21     int x,y;
    22     int pos;
    23 }PT[200005];
    24 
    25 vector<int> vt[2];//记录答案 
    26 
    27 bool cmp(node a,node b)
    28 {
    29     return a.x+a.y > b.x+b.y;
    30 }
    31 
    32 int main()
    33 {
    34     #ifdef DEBUG
    35     freopen("sample.txt","r",stdin);
    36     #endif
    37     
    38     int n;
    39     scanf("%d",&n);
    40     for(int i=1;i<=n;i++)
    41     {
    42         scanf("%d",&PT[i].x);
    43         PT[i].pos=i;//记录位置 
    44     }
    45     for(int i=1;i<=n;i++)
    46         scanf("%d",&PT[i].y);
    47     sort(PT+1,PT+1+n,cmp);
    48     for(int i=1;i<=n;i++)
    49         vt[i%2].push_back(PT[i].pos);
    50     for(int k=1;k>=0;k--)
    51     {
    52         for(int i=0;i<vt[k].size();i++)
    53             printf(i==vt[k].size()-1?"%d
    ":"%d ",vt[k][i]);
    54     }
    55     
    56     return 0;
    57 }

    -

  • 相关阅读:
    好的学习资源
    对paper有用的idea
    斜杠青年
    简书随笔
    点云专业英文单词
    通过 UDP 发送数据的简单范例
    简单的聊天时范例(客户端)
    键盘输入
    简单的传输文件范例
    编写serversocket简单示例1
  • 原文地址:https://www.cnblogs.com/jiamian/p/12271718.html
Copyright © 2011-2022 走看看