zoukankan      html  css  js  c++  java
  • poj1050 to the max

    原文地址:http://blog.sina.com.cn/s/blog_606e17490100f78h.html

    题意:
        很明了,就是求最大子矩阵和。
        现在讲一下最大子矩阵和的求法。
        用2 维数组a[1 : m][1 : n]表示给定的mn列的整数矩阵。子数组a[i1 : i2][j1 : j2]表示左上角和右下角行列坐标分别为(i1, j1)(i2, j2)的子矩阵,其各元素之和记为:

    1)s(i1,i2,j1,j2)=a[i1][i2]+a[i1][i2+1]+……+a[i][j]+……+a[j1][j2];(i1<=i<=i2;j1<=j<=j2)

    推导后可以得到类似一维的最大字段和的问题。
    下面为算法:
    max_sum_submatrix(int m,int n,int a[][n])
    {
        int sum=-99999999;
        int max;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                b[j]=0;
            }
            for(j=i;j<=n;j++)
            {
                for(k=1;k<=n;k++)
                {
                    b[k]+=a[j][k];
                }
                max=max_sum_subseq(n,b);
                sum=sum>max?sum:max;
            }
        }
    下面举例说明:
    如矩阵:
                -2    10    20
                100   -1    -2
                 0      -2  -3

    当i=1时,初始化数组b,使得

    b:0 0 0

     

    当j=1时,k从1递增到n,由算法的第15行可得数组b将首先存储矩阵的第一行的各值,即b为:

    b:-2   10   20

     

    由最大子序列和的函数max_sum_subseq()返回该序列的最大子序列的和值为max=30;

    当j=2时,k从1递增到n,由算法的第15行可得数组b将矩阵a第二行的值分别加到原有各值上,可得数组b为

    b:98    9    18

    同理,返回该序列的最大子序列的和值为max=125。

    当j=3时,k从1递增到n,由算法的第15行可得数组b将矩阵a第三行的值分别加到原有各值上,可得数组b为

    b:98    7     15

     

    同理,返回该序列的最大子序列的和值为max=120。

    到此,i的第一次循环结束。

    当i=2时,从新初始化数组b,使得

    b:0   0    0

     

     

     

    j=2时,k从1递增到n,由算法的第15行可得数组b将首先存储矩阵的第二行的各值,即b为:

    b:100   -1   -2

     

    返回该序列的最大子序列的和值为max=100。

    j=3时,k从1递增到n,由算法的第15行可得数组b将矩阵a第三行的值分别加到原有各值上,可得数组b为

    b:100    -3    -5

     

    返回该序列的最大子序列的和值为max=92。

    到此,i的第二次循环结束。

    当i=3循环结束时,可求出该矩阵的最大子矩阵和值为125

    #include<iostream>
    
    using namespace std;
    
    int a[101][101],b[101];
    
    int max_sub_array(int n)
    {
        int i,j,k;
        int max=0xffffffff;
    
        for(i=0;i<n;++i)
        {
            for(j=i;j<n;++j)
            {
                int sum=0;
                for(k=i;k<=j;++k)
                    sum+=b[k];
                max= max>sum?max:sum;
            }
        }
        return max;
    }
    
    int main()
    {
        int i,j,k,n;
        int sum=0xffffffff;
        cin>>n;
        for(i=0;i<n;++i)
        {
            for(j=0;j<n;++j)
                cin>>a[i][j];
        }
    
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;++j)
                b[j]=0;
    
            for(j=i;j<n;++j)
            {
                for(k=0;k<n;++k)
                    b[k]+=a[j][k];
    
                int max=max_sub_array(n);
                sum = max>sum?max:sum;
            }
        }
        cout<<sum<<endl;
        return 0;
    
    }
  • 相关阅读:
    Windbg 基本调试常识(转)
    善用VS中的Code Snippet来提高开发效率
    如何跟踪调试Software product?
    Visual Studio 2008 每日提示(二十七)
    6步确保 windbg 成功调试 .net(转)
    Visual Studio 2005 重置设置
    Print to Output /To trace runtime
    Windbg安装和配置(转)
    C++与C#交互
    All hands on deck
  • 原文地址:https://www.cnblogs.com/redlight/p/2472002.html
Copyright © 2011-2022 走看看