Blog·Tanky WooABOUTRSS

百练 OJ 2766 最大子矩阵

27 May 2010
这篇博客是从旧博客 WordPress 迁移过来,内容可能存在转换异常。

//ID: 百练 OJ 2766 最大子矩阵 //题目地址: http://poj.grids.cn/problem/2766 //My Name: Tanky_Woo //My Website: C++奋斗乐园|C++学习|算法学习|ACM/ICPC学习 //Website Link: http://www.cpply.com/ //My BBS: C++奋斗乐园|C++论坛|算法论坛|ACM/ICPC论坛 //BBS Link:http://www.cppleyuan.com/ //My Blog:www.wutianqi.com //转载请写上本帖链接 www.cpply.com|www.cppleyuan.com|www.wutianqi.com //及名称"Tanky Woo与ACM一起走过的日子"和“C++奋斗乐园|C++论坛|算法论坛|ACM/ICPC论坛”

 //方法一
/*思想很经典,即利用求数组最长子段的函数。现在考虑如何利用这个函数,从第一行开始,到N行,遍历每种情况:
第i行到第j行上下元素相加,压缩成一个数组*/
#include 
using namespace std;

int N;
int aMatrix[101][101];
int aLine[101];
#define INF -10000000

int maxSubMatrix(int *line);

int main()
{
    //freopen("input_2766.txt", "r", stdin);
    int maxSum = INF;
    int i, j, k , h;
    scanf("%d", &N;);
    for(i = 0; i < N; i++)
        for(j = 0; j < N; j++)
            scanf("%d", &aMatrix;[i][j]);
    for(k = 0; k < N; k++)
    {
        for(h = k; h < N; h++)
        {
            for(j = 0; j < N; j++)
                aLine[j] += aMatrix[h][j];
            int sum = maxSubMatrix(aLine);
            if(sum > maxSum)
                maxSum = sum;
        }
        memset(aLine, 0, sizeof(aLine));


    }
    printf("%d\n", maxSum);
    return 0;
}



int maxSubMatrix(int *line)  //求数组的最长子段
{
    int i;
    int b = line[0], sum = line[0];
    for(i = 1; i < N; i++)
    {
        if(sum > 0)     //这个地方应该是判断b是否大于0,我先写成了sum,结果测试了几组数据是对的,但其实是错的!
            b += line[i];
        else
            b = line[i];

        if(b > sum)
            sum = b;
    }

    return sum;
} 
 //方法二:
/*这题应该算用了DP吧。*/

#include
#include
int a[102][102];
int b[102][102];

int main(){
 //1.两个坐标点就确定了一个矩阵,然后枚举所有的矩阵(直接枚举会超时)
 //2.先计算(0,0)(i.j)确定的矩阵的值b[i][j]
 //3.枚举所有矩阵,利用b[i][j]分割计算 
 int n,ma=0;
 scanf("%d",&n;);
 for(int i=0;i<=n+1;i++){//设置边框
  a[0][i]=0;
  a[n+1][i]=0;
  a[i][0]=0;
  a[i][n+1]=0;
 }

 for(int i=1;i<=n;i++)//输入
  for(int j=1;j<=n;j++){
   scanf("%d",&a;[i][j]);
   if(a[i][j]>ma)ma=a[i][j];
  }


 for(int i=0;i<=n;i++)        //求b[i][j]
  for(int j=0;j<=n;j++)
   for(int p=0;p<=i;p++)
    for(int q=0;q<=j;q++)
     b[i][j]+=a[p][q];
 int sum=0;
 for(int i=1;i<=n;i++)    //枚举矩阵
  for(int j=1;j<=n;j++)
   for(int p=i;p<=n;p++)
    for(int q=j;q<=n;q++){
     sum=0;
     sum=b[p][q]-b[p][j-1]-b[i-1][q]+b[i-1][j-1];
     if(sum>ma)ma=sum;

    }
 printf("%d",ma);

}