hiho一下第86周《Spring Outing》题目分析

8
1

题目大意

有n个人对决定出去游玩,他们有m个备选的游玩地点(1..m)或者选择干脆宅在家(0)。每个人在自己心目中对这m+1(0..m)个地点有一个排名,他们会根据这个列表进行投票。

对于m个地点,按1,2,3,...,m的顺序依次进行表决。当某一个方案票数超过一半时,则投票结束,选择这个地点作为结果。如果m个地点都没有超过半数,那就选择每个人都宅在家里。

现在将每一个人心目中的排名公布出来,即每个人都知道所有人对于m+1个地点的排名。同时他们都非常聪明,会尽量让自己更喜欢的地点胜出,求问最后会选择哪一个地方作为游玩地点。

解题思路

本题的关键在于想明白每个人是如何决策的。原题在Hint中针对样例数据简单(有点模糊)地解释了每个人是如何决策的,对我们有一定的提示作用。请原谅出题人不能在Hint中解释得更加清楚——如果解释得更加清楚的话,基本上就是把解法讲明了。:P

如果我们从最后一轮(对地点m的)投票开始分析,每个人的决策就会一目了然。

假设我们已经进行到了最后一轮,需要对地点m进行投票。这时每个人都知道:如果地点m没有超过半数,那么最终的结果就是宅在家里(地点0)。于是所有认为m比0好的人必然投赞成票,而所有认为0比m好的人必然投反对票。所以如果进入到了最后一轮,那么最终选出的地点是确定的,我们不妨记为result[m]。(如果赞成票多于反对票,那么result[m]=m,否则result[m]=0。对于确定的输入数据,result[m]是唯一确定的。)

现在假设我们进行到倒数第二轮,需要对地点m-1进行投票。根据以上分析,这时每个人都知道:如果地点m-1没有超过半数,那么最终的结果就是result[m]。于是所有认为m-1比result[m]好的人必然投赞成票,而所有认为result[m]比m-1好的人必然投反对票。最终选出的地点也是确定的,我们不妨记为result[m-1]。

以此类推,我们可以求得result[m-2], result[m-3], ..., result[2], result[1]。其中result[1]就是本题的答案。

整个过程写成伪代码为:

result = 0
For i = m .. 1
    vote = 0
    For j = 1 .. n
        If (rank[j][i] < rank[j][result]) Then
            vote = vote + 1
        End If
    End For
    If (vote > n / 2) Then
        result = i
    End If
End For

其中rank[j][i]表示表示第j个人心中,地点i的排名,值越小越靠前;同时把result数组简化为一个变量(这是由于计算result[i]时只需要result[i+1]的值)。

  • 您好,在以此类推的时候到m-2地点时,赞成m-2地点的会投支持票,不支持的有可能喜欢m-1,也有可能喜欢m地点,这时结果怎么是确定的呢?

  • @wuzixiaomanong: 注意到一旦进入第m-1轮投票,result[m-1]是必然的结果。所以到地点m-2时,只要考虑m-2和result[m-1]两个地点即可。

  • 可以这样理解:result[i]是假设进行到第i轮投票,所有轮次确定的最终投票结果,而不单单是第i轮投票的结果

  • 就是说每次投票都是二选一,在输入数据已知的情况下,结果是确定的。

  • 添加评论
  • reply

write answer 切换为英文 切换为中文


转发分享