现在的位置: 首页 > 综合 > 正文

poj 1050

2013年10月16日 ⁄ 综合 ⁄ 共 1061字 ⁄ 字号 评论关闭

此题数据规模不大,可以通过暴力水过,代码如下

#include <iostream>
using namespace std;
const int maxn=101;
int num[maxn][maxn]; 
int n;
int getM()
{
    int i,j,k,i2,j2;
    int f[maxn];
    int max=-1<<20,sum;
    for(i=1;i<=n;i++)
    {
        memset(f,0,sizeof(f));
        for(j=i;j<=n;j++)
        {
            for(k=1;k<=n;k++)
            {
                f[k]+=num[j][k];
            }
            for(i2=1;i2<=n;i2++)
            {
                sum=0;
                for(j2=i2;j2<=n;j2++)
                {
                    sum+=f[j2];
                    if(sum>max) max=sum;
                }
            }
        }
    }
    return max;
}
int  main()
{
    while(cin>>n)
    {
        int i,j;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
                cin>>num[i][j];
        }
        int max=getM();
        cout<<max<<endl;
    }
    return 0;
}

可以通过dp提高效率,对于一维矩阵,设f[i]为以i为终点的最大连续段,那么可知f[i]=max(m[i],f[i-1]+m[i],即)当f[i-1]<0时,f[i]=m[i](m为此一维矩阵),当f[i-1]>0,f[i]=f[i-1]+m[i],所以最终的最大值就是f[i]中的最大值。时间效率从暴力O(n4)优化到O(n3).

#include <iostream>
using namespace std;
const int maxn=101;
int num[maxn][maxn]; 
int n;
int getM()
{
    int i,j,k;
    int f[maxn];
    int max=-1<<20,sum;
    for(i=1;i<=n;i++)
    {
        memset(f,0,sizeof(f));
        for(j=i;j<=n;j++)
        {
            for(k=1;k<=n;k++)
            {
                f[k]+=num[j][k];
            }
            sum=0;
            for(k=1;k<=n;k++)
            {
                sum=f[k]>(sum+f[k])?f[k]:(sum+f[k]);
                if(sum>max) max=sum;
            }
        }
    }
    return max;
}
int  main()
{
    while(cin>>n)
    {
        int i,j;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
                cin>>num[i][j];
        }
        int max=getM();
        cout<<max<<endl;
    }
    return 0;
}

抱歉!评论已关闭.