[POJ 2444] Partition a Matrix 暴力

http://poj.org/problem?id=2444

题意:用两条线将矩阵切成三部分, 两天直线可以平行也可以垂直, 如果垂直的话有一条就是射线(要不然变成四部分了)

思路:情况不多 暴力枚举。。。。

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef __int64 ll;
const ll inf = 0x7fffffffffffffff;

ll minn;
int n, m;
ll dp[505][505];
int mapn[505][505];

inline ll abs(ll a){
    return a >= 0 ? a : -a;
}

void Init()  //初始化,求(1, 1)到(i,k)矩阵的和
{
    for(int i = 0; i <= n || i <= m; i++){
        dp[i][0] = dp[0][i] = 0;
    }
    for(int i = 1; i <= n; i++){
        for(int k = 1; k <= m; k++){
            dp[i][k] =dp[i-1][k] + dp[i][k-1] - dp[i-1][k-1] + mapn[i][k];
        }
    }
}

inline ll fun(int up, int dw, int lf, int rg) // 求和
{
    ll sum = 0;
    sum += dp[dw][rg] + dp[up-1][lf-1] - dp[up-1][rg] - dp[dw][lf-1];
    return sum;
}

inline void fuck(ll sum1, ll sum2, ll sum3)
{
    ll sum = abs(sum1 - sum2) + abs(sum1 - sum3) + abs(sum2 - sum3);
    if(sum < minn)
        minn = sum;
}

int main()
{
    while(scanf("%d%d", &n, &m) && (m || n)){
        for(int i = 1; i <= n; i++){
            for(int k = 1; k <= m; k++){
                scanf("%d", &mapn[i][k]);
            }
        }
        Init();
        minn = inf;
        for(int i = 1; i < n; i++){ //垂直情况
            for(int k = 1; k < m; k++){
                ll sum1 = fun(1, i, 1, k);
                ll sum2 = fun(1, i, k+1, m);
                ll sum3 = fun(i+1, n, 1, k);
                ll sum4 = fun(i+1, n, k+1, m);
                fuck(sum1+sum2, sum3, sum4);
                fuck(sum1+sum3, sum2, sum4);
                fuck(sum2+sum4, sum1, sum3);
                fuck(sum3+sum4, sum1, sum2);
            }
        }
        for(int i = 1; i < n-1; i++){ //平行
                ll sum1 = fun(1, i, 1, m);
            for(int k = i+1; k < n; k++){
                ll sum2 = fun(i+1, k, 1, m);
                ll sum3 = fun(k+1, n, 1, m);
                fuck(sum1, sum2, sum3);
            }
        }
        for(int i = 1; i < m-1; i++){//平行
                ll sum1 = fun(1, n, 1, i);
            for(int k = i+1; k < m; k++){
                ll sum2 = fun(1, n, i+1, k);
                ll sum3 = fun(1, n, k+1, m);
                fuck(sum1, sum2, sum3);
            }
        }
        printf("%I64d\n", minn);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

achonor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值