AtCoder Context ABC 173 D - Chat in a Circle

本文章为原创文章,未经过允许不得转载
原题链接
运行要求
运行时间限制: 2sec
内存限制: 1024MB

题目
你在玩一款叫做ATChat的网游,结束游戏教程后,和当时在场的N个玩家一起去一个场景集合。给这N个玩家分配1到N的号码。i号玩家(1<=i<=N)的友好度为Ai。
N位玩家按照一个设定好的顺序依次抵达现场。你为了不让自己迷失,让已经到达的玩家围成一个圆圈,并且按照自己喜欢的顺序安插他们到相应的位置。
除了最开始抵达的玩家以外,其他的玩家在抵达的时候能够感到一定的舒适度。这个舒适度是顺时针离这个玩家最近的玩家,逆时针离这个玩家最近的玩家,两者友好度中最小的那个友好度。
最开始抵达的玩家感受到的舒适度是0。

你能够决定N位玩家的抵达顺序,并能够决定N位玩家在圆环中的安插位置。
请问能够让所有玩家的舒适度所能达到的最大值是多少。

输入前提条件

  • 所有的输入都为整数
  • 2 <= N <= 2 * 10 ^ 5
  • 1 <= Ai <= 10 ^ 9

输入
输入按照以下形式标准输入

N
A1 A2 A3 A4 A5

输出
N位玩家的舒适度之和的最大值


例1
输入

4 
2 2 1 3

输出

7

AtCoder Context ABC 173 D - Chat in a Circle_第1张图片
如图所示,按照
4号玩家
2号玩家
1号玩家
3号玩家
的顺序抵达,并且按照如图所示的顺序插入,可以得到最大的舒适度的和值7

例2
输入

7
1 1 1 1 1 1 1

输出

6

读懂题目
相当于有一个环,有一个一维数值ARR
把这个一维数组上的值Ai排到环上。

除了第一个排到环上的数以外
其他的数都会取与它相邻的数的最小值,加到最后的结果上
求最后结果的最大值

解题思路
首先,例1中可以隐约感觉到要从最大的数开始排。
AtCoder Context ABC 173 D - Chat in a Circle_第2张图片
如图所示
上面的绿色的圈表示从小到达的顺序安排2,6
下面的蓝色的圈表示从大到小的顺序安排6,2

上面的情况6的友好度被2稀释
下面2在6的后面被派上,因此成功获取了6的友好度

再次,我们可以发现如果按照由大到小的顺序排列,某一个节点插入后,他的影响范围会有两次。下一个元素插在它的左边,下下一个元素插入到它的右边。
AtCoder Context ABC 173 D - Chat in a Circle_第3张图片
如图所示,元素8插入以后,它的下一个元素7排在它的左边。下下一个元素6排在它的右边。这样的话8成了7和6的友好度。

AtCoder Context ABC 173 D - Chat in a Circle_第4张图片
如图所示,给定数组9,8,7,6,3,2,2
9影响到了8
8影响到了7,6
7影响到了3,2
6影响到了2

这样的话,我们有了这么一个思路
把数组由大到小排序。遍历
第一个会影响第二个元素。
除了第一个以外,剩下的会影响到下一个,下下一个元素。并且加起来。
影响范围到达数组末尾后,遍历停止。
按照上面的思路遍历数组9,8,7,6,3,2,2
AtCoder Context ABC 173 D - Chat in a Circle_第5张图片

代码
方法一

N = int(input())
ARR = list(map(int,input().split()))
def calculate(n, arr):
    endIndex = 0
    ans = 0

    arr = sorted(arr, reverse=True)
    for i in range(n):

        if i == 0:
            ans += arr[i]
            endIndex += 1
            continue

        endIndex += 1
        if endIndex >= n:
            break
        ans += arr[i]

        endIndex += 1
        if endIndex >= n:
            break
        ans += arr[i]

    print(ans)

calculate(N, ARR)

方法二

import heapq
N = 4
ARR = [2, 2, 1, 3]

N = 7
ARR = [1, 1, 1, 1, 1, 1, 1]

N = int(input())

ARR = list(map(int,input().split()))
def calculate(n, arr):
    result = []

    arr = sorted(arr,reverse=True)

    heapq.heappush(result,-1 * arr[0])

    ans = 0
    for i in range(1,n):
        ans -= heapq.heappop(result)

        heapq.heappush(result,-1 * arr[i])
        heapq.heappush(result, -1 * arr[i])

    print(ans)

calculate(N, ARR)

AtCoder Context ABC 173 D - Chat in a Circle_第6张图片

总结
本题考查了对于题目中规律的抽取能力
从大到小排序
第1个节点会影响第二个节点
第2个节点以外的节点会影响,下面两个节点

※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
二维码.jpg


你可能感兴趣的:(python3)