[WC 2005]友好的生物

时间:2022-09-15 19:15:20

Description

$W$ 星球是一个和地球一样气候适宜、物种聚集的星球。经过多年的研究,外星生物学家们已经发现了数万种生物,而且这个数字还在不断增大。

$W$ 星球上的生物很有趣,有些生物之间很友好,朝夕相伴,形影不离;但有些却很敌对,一见面就难免发生战斗。为了能够更好地了解它们之间的友好程度,外星生物学家希望进行一些量化的计算。他们发现,两种生物之间的友好程度和它们的 $K$ 种属性有关,暂且将它们编号为属性 $1$、属性 $2$、……、属性 $K$,这些属性都是可以进行量化的。外星生物学家研究发现,如果前 $K$-$1$ 种属性的差别越大,这两种生物就越友好;但是属性 $K$ 与众不同,这种属性差别越小的两种生物越友好。

因此他们猜想是不是可以用这样一个公式量化两种生物之间的友好程度:$$Friendliness=(\sum_{i=1}^{k-1} C_i*d_i)-C_K*d_K$$

其中 $C_i$ 是非负常数,$d_i$是属性$i$的差别。如果知道了每种生物的各种属性,利用上述公式就很容易算出它们之间的友好程度了。现在,外星生物学家们想问一问:在目前发现的这些生物当中,关系最友好的那对生物是哪一对呢?它们之间的友好程度是多少?

Input

输入文件的第一行是两个整数 $N$ 和 $K$,分别表示目前发现的生物种数和属性的种数。

第二行有 $K$ 个非负整数 $C_i$,即计算友好程度时所需的常数。

接下来的 $N$ 行,描述每种生物,按照先后顺序依次编号为生物 $1$、生物$2$、……、生物 $N$。每一行都有 $K$ 个整数,给出该种生物的各项属性值,按照先后顺序依次编号为属性$1$、属性 $2$、……、属性 $K$。

Output

输出文件包含两行。第一行为两个整数 $i$ 和 $j$($i$ ≠ $j$),表示你所找到的关系最友好的两种生物为生物 $i$ 和生物 $j$。若最友好的不止一对,输出任意一对。

第二行为一个整数,表示生物 $i$ 和生物 $j$ 之间的友好程度。

Sample Input

5 3
1 2 3
-5 3 2
-2 3 0
0 5 9
3 4 -1
-10 -11 7

Sample Output

3 5
36

HINT

【样例说明】

生物 $3$ 和 $5$ 之间的友好程度为$1*|0-(-10)|+2*|5-(-11)|-3*|9-7|$=$36$。

【约定】

○$2$ ≤ $N$ ≤ $100,000$

○$2$ ≤ $K$ ≤ $5$

○$0$ ≤ $C_i$ ≤ $100$。

○每种生物的各项属性值不小于$-10000$ 且不大于 $10000$

○最大的友好程度一定大于 $0$

题解

多年前的一道 $NOIp$ 模拟题。今天拿出来整理一下...题解在这里

 //It is made by Awson on 2018.1.26
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = ;
const int INF = 1e9; int n, k, c[], a[N+][], S[];
int ans, la, lb;
struct tt {
int a, b, id;
bool operator < (const tt &x) const {
return b < x.b;
}
}t[N+]; void cal() {
for (int i = ; i <= n; i++) {
t[i].b = S[k]*a[i][k]; t[i].a = ; t[i].id = i;
for (int j = ; j <= k; j++) t[i].a += S[j]*a[i][j];
}
sort(t+, t+n+); int maxn = -INF, maxi = ;
for (int i = ; i <= n; i++) {
if (ans < maxn-t[i].a) ans = maxn-t[i].a, la = maxi, lb = t[i].id;
if (maxn < t[i].a) maxn = t[i].a, maxi = t[i].id;
}
}
void dfs(int cen) {
if (cen > k) {cal(); return; }
S[cen] = -; dfs(cen+);
S[cen] = ; dfs(cen+);
}
void work() {
scanf("%d%d", &n, &k);
for (int i = ; i <= k; i++) scanf("%d", &c[i]);
for (int i = ; i <= n; i++) for (int j = ; j <= k; j++) scanf("%d", &a[i][j]), a[i][j] *= c[j];
dfs(); if (la > lb) Swap(la, lb); printf("%d %d\n%d\n", la, lb, ans);
}
int main() {
work();
return ;
}