2020暑期牛客多校第六场C.Combination of Physics and Maths(贪心+数学)

题目链接:https://ac.nowcoder.com/acm/contest/5671/C
题意:选取任意数量的行和列,这些行和列的交点取出来作为一个新的矩阵。P=F/S,F值为矩阵内所有值的和,S为矩阵最下面一行的值的和,求P的最大值
解题思路:
贪心做法,思路是因为S只取最下面的数值和,所以对于新矩阵最下行上面的行全部都取,这样S不变的情况下,F最大
up[i][j]记录下第j列往下i个数的总和
令第i列P为 Y X \frac{Y}{X} XY,第j列P为 M N \frac{M}{N} NM, Y X \frac{Y}{X} XY+ M N \frac{M}{N} NM<= Y M X N \sqrt[]\frac{YM}{XN} XNYM ,当且仅当 Y X \frac{Y}{X} XY= M N \frac{M}{N} NM时,取到最大值为 Y X \frac{Y}{X} XY,所以列和列之间不要合并在一起。
所以,只需要遍历每一列,然后贪心的选择列的最大P即可

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int inf = 0x3f3f3f3f;
int n, m, t, a[222][222], up[222][222];
double x;
int main() {
    scanf("%d", &t);
    while (t--) {
        memset(up, 0, sizeof(up));
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                scanf("%d", &a[i][j]); 
                up[i][j] = up[i - 1][j] + a[i][j];
            }
        }
        double ma = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                x = 1.0 * up[i][j] / a[i][j];
                ma = max(ma, x);
            }
        }
        printf("%.8f\n", ma);
    }
    return 0;
}

你可能感兴趣的:(基础专题)