题目描述
沈灵是福建中医药大学的一位医学博士,一直从事癌症的研究和治疗。某次实验时她很好奇人身体里 面的抗病毒细胞和病变细胞是怎么样消灭和吞噬掉对方。于是她就设定抗病毒细胞和病变细胞各自组 成一方,组建各自的细胞进行对战。现在双方共有n个队长(n为偶数并且不小于4),任意两个队长 之间有一个默契值,表示这两位队长组成一对组合作战时,该组合的力量有多大。对战开始前,所有 的队长都是自由的(如果某一位自由队长选择了某一方并成为其中一员,那么他就不是自由队长了; 意思是:自由队长不归属于任何一方)。抗病毒细胞和病变细胞要从自由队长中选择队长组建自己的 战队。规则为:抗病毒细胞先从自由队长中选一个加入自己的战队,然后病变细胞也从自由队长中选 择一位加入自己的战队。紧接着一直按照“抗病毒细胞→病变细胞→……”的顺序选择自由队长,直 到所有的自由队长被双方选完。然后,自动从双方战队中各挑选出一对默契值最高的队长组合代表自己的战队进行二对二对战,拥有更高默契值的一对队长获胜。以此种形式表示对战,拥有获胜队长组 合的一方获胜。
已知病变细胞一方选择队长的原则是尽量破坏抗病毒细胞下一步将组合的最强队长,采取的具体策略 为:任何时刻,轮到病变细胞挑选时,它会尝试将抗病毒细胞中的每个队长与当前每个自由队长进行 一一匹配,找出所有配对中默契值最高的那对队长组合,并将该组合中的自由队长选入自己的战队。
下面举例说明病变细胞的选自由队长策略,例如,对战中一共有6个队长,他们相互之间的默契值如 下表所示:
双方选最长过程如下所示:
抗病毒细胞想知道,如果病变细胞在一局对战中始终坚持上面这个策略,那么自己有没有可能必胜? 如果有,在所有可能的胜利局中,自己那对用于对战的队长组合的默契值最大是多少?
假设整个对战中,对战双方在任何时候都能看到自由队长队中的队长和对方战队的队长。为了简化问 题,保证对于不同的队长组合,其默契值均不相同。
输入格式
第一行为一个偶数n,表示自由队长的个数。
第2行到第n行里,第
(
i
+
1
)
(i+1)
(i+1)行有
(
n
−
i
)
(n−i)
(n−i)个非负整数,表示i号队长和
i
+
1
,
i
+
2
,
…
…
,
n
i+1,i+2,……,n
i+1,i+2,……,n号队长之间 的默契值(
0
≤
0≤
0≤默契值
≤
1
,
000
,
000
,
000
≤1,000,000,000
≤1,000,000,000)。
输出格式
对于给定的输入,存在可以让抗病毒细胞获胜的选队长顺序,则输出1,同时另起一行输出所有获胜
的情况中,抗病毒细胞最终选出的队长组合的最大默契值。
如果不存在可以让抗病毒细胞获胜的选将顺序,则输出0。
输入输出样例
输入 #1
6
5 28 16 29 27
23 3 20 1
8 32 26
33 11
12
输出 #1
1
32
输入 #2
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
输出 #2
1
77
输入 #3
10
42 24 10 29 27 12 58 65 78
31 8 16 26 80 6 45 67
25 3 36 11 5 9 24
33 20 17 13 24 36
15 77 9 68 21
4 50 49 39
19 67 47
20 98
78
输出 #3
1
78
说明/提示
数据范围
对于47%的数据,
n
≤
10
n≤10
n≤10。
对于80%的数据,
n
≤
18
n≤18
n≤18。
对于100%的数据,
n
≤
500
n≤500
n≤500。
样例解释
对于样例1,首先抗病毒细胞拿走5号队长;病变细胞发现5号队长和剩下自由队长中的4号默契值最 高,于是拿走4号;抗病毒细胞接着拿走3号;病变细胞发现3、5号队长之一和剩下的自由队长配对的 所有组合中,5号和1号默契值最高,于是拿走1号;抗病毒细胞接着拿走2号;病变细胞最后拿走6 号。在抗病毒细胞手里的2,3,5号队长中,3号和5号配合最好,默契值为32,而病变细胞能推出的 最好组合为1号和6号,默契值为27。结果为抗病毒细胞胜,并且这个组合是抗病毒细胞用尽所有方法 能取到的最好组合。
解题思路
其实这道题就是洛谷上的原题——P1199 三国游戏。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<cmath>
using namespace std;
long long a[600][600],n,ans;
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(i!=j)
{
scanf("%lld",&a[i][j]);
a[j][i]=a[i][j];
}
}
}
for(int i=1;i<=n;i++)
{
sort(a[i]+1,a[i]+n+1);
ans=max(ans,a[i][n-1]);
}
printf("1\n%lld",ans);
}