矩阵一分为二,两个部分差值最小

Tips:这是一个矩阵前缀和的实例,有关前缀和请看我上一篇

问题描述:

小美有一个矩形的蛋糕,共分成了 n 行 m 列,共 n * m 个区域,每个区域是一个小正方形,已知蛋糕每个区域都有一个美味度。她想切一刀把蛋糕切成两部分,自己吃一部分,小团吃另一部分。 

小美希望两个人吃的部分的美味度之和尽可能接近,请你输出|s1 - s2|的最小值。(其中 s1 代表小美吃的美味度,s2 代表小团吃的美味度)。 请务必保证,切下来的区域都是完整的,即不能把某个小正方形切成两个小区域。

来源:卡码网130题

思路:只有一刀,将一个矩阵一分为二,只有两种切法,一个是横着切,一个竖着切。这就可以利用前缀和。比如我们在第i行一分为二,那么这两个部分的插值就可以表示为上半部分:以[0][0]为左上角,右下角[i][j]的矩阵值。下半部分:以[i+1][0]为左上角,右下角[n-1][m-1]的矩阵值。差值表示:

\Delta s = sum[i][j] - (sum[n-1][m-1]] - sum[i][j])

具体代码:

#include <iostream>
#include <vector>
#include <climits>

using namespace std;

int main() {
    int n,m;
    cin >> n>>m;
    
    vector<vector<int>> matrix(n,vector<int>(m));
    //保存前缀和
    vector<vector<int>> sum_matrix(n+1,vector<int>(m+1,0));
    //int sum = 0;
    
    for(int i = 0;i < n;++i) {
        for(int j = 0;j < m;++j) {
            cin >> matrix[i][j];
            //sum += matrix[i][j];
            
            sum_matrix[i+1][j+1] = matrix[i][j] + sum_matrix[i][j+1] + sum_matrix[i+1][j] - sum_matrix[i][j];
        }
    }
    
    int res = INT_MAX;
    
    //开始切蛋糕
    //竖着切蛋糕 两个人的差距最小
    for(int j = 1;j <= m;++j) {
        int s1 = sum_matrix[n][j];
        int s2 = sum_matrix[n][m] - s1;
        res = min(res,abs(s1-s2));
    }
    
    //横着切蛋糕,两个人差距最小
    for(int i = 1;i <= n;++i) {
        int s1 = sum_matrix[i][m];
        int s2 = sum_matrix[n][m] - s1;
        res = min(res,abs(s1-s2));
    }
    
    cout << res << endl;
    
}

输入:

2 3
1 1 4
5 1 4

输出:

0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值