zoukankan      html  css  js  c++  java
  • 三国游戏

    D14561. 【NOIP2010P】三国游戏

    时间限制:1.0s 内存限制:128.0MB 代码提交间隔:1分钟(现在可以提交)
    输入文件名:sanguo.in 输出文件名:sanguo.ans
    试题来源:NOIP
    问题描述
      小涵很喜欢电脑游戏,这些天他正在玩一个叫做《三国》的游戏。
      在游戏中,小涵和计算机各执一方,组建各自的军队进行对战。游戏中共有N  位武将(N为偶数且不小于4),任意两个武将之间有一个“默契值”,表示若此两位武将作为一对组合作战时,该组合的威力有多大。游戏开始前,所有武将都是自由的(称为自由武将,一旦某个自由武将被选中作为某方军队的一员,那么他就不再是自由武将了),换句话说,所谓的自由武将不属于任何一方。游戏开始,小涵和计算机要从自由武将中挑选武将组成自己的军队,规则如下:小涵先从自由武将中选出一个加入自己的军队,然后计算机也从自由武将中选出一个加入计算机方的军队。接下来一直按照“小涵→计算机→小涵→……”的顺序选择武将,直到所有的武将被双方均分完。然后,程序自动从双方军队中各挑出一对默契值最高的武将组合代表自己的军队进行二对二比武,拥有更高默契值的一对武将组合获胜,表示两军交战,拥有获胜武将组合的一方获胜。
      已知计算机一方选择武将的原则是尽量破坏对手下一步将形成的最强组合,它采取的具体策略如下:任何时刻,轮到计算机挑选时,它会尝试将对手军队中的每个武将与当前每个自由武将进行一一配对,找出所有配对中默契值最高的那对武将组合,并将该组合中的自由武将选入自己的军队。
      下面举例说明计算机的选将策略,例如,游戏中一共有6 个武将,他们相互之间的默契值如下表所示
      双方选将过程如下所示:
      小涵想知道,如果计算机在一局游戏中始终坚持上面这个策略,那么自己有没有可能必
      胜?如果有,在所有可能的胜利结局中,自己那对用于比武的武将组合的默契值最大是多
      少?
      假设整个游戏过程中,对战双方任何时候均能看到自由武将队中的武将和对方军队的武
      将。为了简化问题,保证对于不同的武将组合,其默契值均不相同。
    输入格式
      第一行为一个偶数N,表示武将的个数。
      第2 行到第N 行里,第(i+1)行有(N-i)个非负整数,每两个数之间用一个空格隔开,表示i 号武将和i+1,i+2,……,N 号武将之间的默契值(0 ≤ 默契值≤ 1,000,000,000)。
    输出格式
      若对于给定的游戏输入,存在可以让小涵获胜的选将顺序,则输出1,并另起一行输出所有获胜的情况中,小涵最终选出的武将组合的最大默契值。
      如果不存在可以让小涵获胜的选将顺序,则输出0。
    样例输入

    6
    5 28 16 29 27
    23 3 20 1
    8 32 26
    33 11
    12

    8
    42 24 10 29 27 12 58
    31 8 16 26 80 6
    25 3 36 11 5
    33 20 17 13
    15 77 9
    4 50
    19
    样例输出

    1
    32

    1
    77
    输入输出样例说明
      首先小涵拿走5 号武将;计算机发现5 号武将和剩下武将中的4 号默契值最高,于是拿走4 号;小涵接着拿走3 号;计算机发现3、5  号武将之一和剩下的武将配对的所有组合中,5 号和1 号默契值最高,于是拿走1 号;小涵接着拿走2 号;计算机最后拿走6  号。在小涵手里的2,3,5 号武将中,3 号和5 号配合最好,默契值为32,而计算机能推出的最好组合为1 号和6  号,默契值为27。结果为小涵胜,并且这个组合是小涵用尽所有方法能取到的最好组合。
    数据规模和约定
      对于40%的数据有N≤ 10。
      对于70%的数据有N≤ 18。
      对于100%的数据有N≤ 500。

    思路:

    我们要知道计算机,是一个没有思想没有灵魂的器物,空有一具躯壳,但是它内心是空洞的,是黑暗的。计算机终日任人摆布,没有属于自己的思想,浑浑噩噩,这样的生活毫无意义。
    以上是随性而言,下面进入正题。
    计算机的bp是很愚蠢的,依照贪心策略每次选取战力最大的一对英雄的一个,这样就像搅屎棍一样任何一对满战力英雄都无法选取出。然而人类将发挥自己卓越的才能选到战力次大的英雄组,如此只要从各个英雄的所有搭配中选出战力次大的一组,然后选出最大值即可。
    具体实现轻而易举,建一个邻接矩阵,然后对每一行排序,然后在找出所有a[i][n-1]中最大的一个即可。

    Code:

    #include<bits/stdc++.h>
    
    using namespace std;
     
    int n;
    
    int hero[510][510];
    
    int ans = -1;
    
    int main(){
            freopen("sanguo.in","r",stdin);
            freopen("sanguo.ans","w",stdout);
            cin >> n;
            for (int i = 1; i <= n; i++)
                    for (int j = i + 1; j <= n; j++) {
                            int x;
                            cin >> x;
                            hero[i][j] = hero[j][i] = x;
                    }//注意读入时的坐标下标
            for (int i = 1; i <= n; i++)
                    sort(hero[i] + 1, hero[i] + n + 1);
            for (int i = 1; i <= n; i++)
                    ans = max(ans,hero[i][n - 1]);
            cout << 1 << endl << ans << endl;
            return 0;
    }
    

    !注意输出文件名

  • 相关阅读:
    OpenLDAP备份和恢复
    OpenLDAP搭建部署
    Python正则表达式
    ansible学习
    Jenkins学习
    docker学习2
    让阿里告诉你, iOS开发者为什么要学 Flutter !
    用UIKit和UIView在视图上执行iOS动画
    iOS开发如何面对疫情过后的面试高峰期 !
    如何写好一个UITableView
  • 原文地址:https://www.cnblogs.com/sun915/p/9507389.html
Copyright © 2011-2022 走看看