题目大意:给定一矩阵,求一个子矩阵(可以非连续),使得子矩阵所有数的和除以子矩阵最后一行的和最大,输出这个比值。
假如我们对于每列都进行这样的计算:从第一行到终止行(任一行)的数之和除以终止行的数,那么我们可以得到以每一列的某些行作为矩阵的最大值,如果以多列作为矩阵,合并后的值一定不会大于合并前的值,原因
设较大的为a/b,较小的为c/d;
合并后为(a+c)/(b+d);
a/b=(a*b+a*d)/(b*b+b*d);
(a+c)/(b+d)=(a*b+c*b)/(b*b+b*d);
a/b-(a+c)/(b+d)=(a*d-c*b)/(b*b+b*d);
a/b>c/d=>a/b-c/d=(a*d-b*c)/b*d>0=>a*d>b*c;
所以a/b-(a+c)/(b+d)=(a*d-c*b)/(b*b+b*d)>0;
即a/b>(a+c)/(b+d)
如果a/b=c/d,则符号为=
所以我们只需要寻找单列的最大值,总用时为O(Tnm)。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 440;
int date[N];
int main() {
int t;
scanf("%d", &t);
while (t--) {
memset(date, 0, sizeof(date));
int n,m;
scanf("%d %d", &n,&m);
double ans;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int temp;
scanf("%d", &temp);
date[j] += temp;
ans = max(ans, 1.0*date[j] / temp);
}
}
printf("%.8lf\n", ans);
}
}