Combination of Physics and Maths

题目大意:给定一矩阵,求一个子矩阵(可以非连续),使得子矩阵所有数的和除以子矩阵最后一行的和最大,输出这个比值。

假如我们对于每列都进行这样的计算:从第一行到终止行(任一行)的数之和除以终止行的数,那么我们可以得到以每一列的某些行作为矩阵的最大值,如果以多列作为矩阵,合并后的值一定不会大于合并前的值,原因

	设较大的为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
#include
#include

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);
	}
}

你可能感兴趣的:(补题,算法)