POJ 1050

描述

給定一個二維數組,包含正整數、負整數,一個子矩陣是在該數組中,任何鄰近的1*1或更大的子數組。矩陣的和是矩形中所有元素的和。在該問題中,有最大和的子矩陣稱爲最大子矩陣。
例如,給定二維數組:

0941221876400212

最大子矩陣是左下角:
941218

該子矩陣的和爲15

輸入

輸入包含N*N整形數組,
輸入的第一行是一個正整數N,表示二維方陣的邊長。
N2 個整數,空白分隔(空格和換行),按行排列。0<N100,n[127,127]n

輸出

最大子矩陣的和

輸入樣例

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

8 0 -2

輸出樣例

15

思路

1 動態規劃

動態規劃,Dynamic programming,簡稱:DP
1. 二維數組劃分爲多行一維數組,每行進行計算
2. 每行一維數組的最大子數組和。
3. 累加總和

2具體說明

  1. 一維數組的最大子數組和
    描述:
    給定數組:
    a[0],a[1],a[2],...,a[n] ,求其中連續的一段子數組,使子數組的和最大。
    dp算法:
    a[i] 爲第i 個元素,dp[i] 爲以a[i] 結尾的最大子數組和,則:
    dp[i]=max{a[i],dp[i1]+a[i]}

    dp[i1]>0 , 則 dp[i]=dp[i1]+a[i]
    dp[i1]<0 , 則 dp[i]=a[i]
    由於不用記錄dp[i]中的位置信息(選取的i),dp[i]可用變量dp代替:
    dp>0 , 則 dp=dp+a[i]
    dp<0 , 則 dp=a[i]
  2. 二維的最大子矩陣和
    枚舉行的組合,
    求出(1,1),(1,2),…,(1,n)的最大值
    再求(2,2),(2,3),…,(2,n)的最大值,直到(m,n)

C 實現

#include <stdio.h>
#define MAXSIZE 101
//所有數組從[1][1]位置開始計數,避免混亂

// 求一維數組中最大的子數組和
int maxArray(int n, int arr[])
{
    int i, sum = 0, max = arr[1];
    for (i = 1; i <= n; ++i)
    {
        if(sum > 0)
        {
            sum += arr[i];
        }
        else
        {
            sum = arr[i];
        }
        if(sum > max)
        {
            max = sum;
        }
    }
    return max;
}

// 求二維數組中最大子矩陣和
int maxMatrix(int n, int arr[][MAXSIZE])
{
    int max = arr[1][1];
    int sum = 0;
    int i,j,k;
    int temp_arr[MAXSIZE];
    for(i = 1; i <= n; ++i)
    {
        for(j = 1; j <= n; ++j)//只有起始行改變,temp_arr數組才初始化
        {
            temp_arr[j] = 0;
        }
        for(j = i; j <= n; ++j)//枚舉行的範圍,j爲當前行,循環從i行到第n行
        {
            for(k = 1; k <= n; ++k)//k爲j行的每個元素
            {
                temp_arr[k] += arr[j][k];// temp_arr[k]表示從第i行到第n行中第k列的總和
            }
            sum = maxArray(n, temp_arr); //求出該行中最大的子數組和
            if(sum > max)
            {
                max = sum;
            }
        }
    }
    return max;
}
int main()
{

    int n,i,j,max;
    int arr[MAXSIZE][MAXSIZE];
    while(~scanf("%d", &n))//while依次讀入多組二維數組,~scanf("%d", &n)相當於scanf("%d", &n) != EOF  
    {
        for(i = 1; i <= n; ++i)
        {
            for(j = 1; j <= n; ++j)
            {
                scanf("%d", &arr[i][j]);
            }
        }
        max = maxMatrix(n,arr);
        printf("%d\n",max);
    }

    return 0;
}

參考

http://blog.csdn.net/hitwhylz/article/details/11848439

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章