1. 程式人生 > >動歸集6.P1719 最大加權矩形

動歸集6.P1719 最大加權矩形

敲會啦!不過什麼時候可以堂堂正正地去刷提高啊?

這次與最小欄位區別為原為線段,現為矩形

使用到的知識點為矩陣壓縮,還有字首和

你一定要記住啊!把演算法寫成半模擬的估計只有老萌新你能幹的出來啦

題目:

校長先給他們一個N*N矩陣。要求矩陣中最大加權矩形,即矩陣的每一個元素都有一權值,權值定義在整數集上。從中找一矩形,矩形大小無限制,是其中包含的所有元素的和最大 。矩陣的每個元素屬於[-127,127],例如

0 –2 –7 0 在左下角: 9 2

9 2 –6 2 -4 1

-4 1 –4 1 -1 8

-1 8 0 –2 和為15

輸入格式:

第一行:n,接下來是n行n列的矩陣。

輸出格式:

最大矩形(子矩陣)的和。

輸入樣例#1: 複製

4
0 -2 -7 0
 9 2 -6 2
-4 1 -4  1 
-1 8  0 -2

輸出樣例#1: 複製

15

說明

n<=120

#include<iostream>
using namespace std;
int n,a[130][130];
int man(int k,int r)
{
    //cout<<k<<" "<<r<<endl;
    int b[n+3],f[n+3];
    //cout<<a[k][0]<<" "<<a[r][0]<<endl;
    b[1]=a[k][1]-a[r][1];
    f[1]=b[1];
    for(int i=2;i<=n;i++)
    {
        //cout<<a[k][i]<<" "<<a[r][i]<<" ";
        b[i]=a[k][i]-a[r][i];
        f[i]=b[i]+f[i-1];
        //cout<<b[i]<<" "<<f[i]<<endl;
    }
    
    int maxx=f[1];
    f[0]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<i;j++)
        {
            maxx=max(maxx,f[i]-f[j]);
        }
    }
    return maxx;
}
int maxn()
{
    int s=a[1][1];
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<i;j++)
        {
            int p=man(i,j);
            //cout<<i<<" "<<j<<endl;
            s=max(s,p);
        }
    }
    return s;
}
int main()
{
    cin>>n;

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
            a[i][j]+=a[i-1][j];
        }
    }
    cout<<maxn()<<endl;
    return 0;
}