1050To the Max

我的代码超时了,多么简洁的代码啊!!!!!!!就这样超时了

#include "iostream"
using namespace std;
int main(){
  int n,i,j,k,l,table[100][100],max,p,q,total;
  cin>>n;
  for(i=0;i<n*n;i++){
      cin>>table[i/n][i%n];
  }
  max=0;
  for(i=0;i<n;i++)
    for(j=0;j<n;j++)
      for(k=i+1;k<n;k++)
        for(l=j+1;l<n;l++){
           total=0;
           for(p=i;p<=k;p++)
             for(q=j;q<=l;q++)
              total+=table[p][q];
           if(total>max)max=total;
        }
  cout<<max<<endl;
}

网上的代码,也顺便把人家的解说给弄上去

 

这道题可以借鉴求最大和的连续子序列的方法来做;
在i,j行之间求出每一列这之间的和,那么这个和的最大连续子序列和就是所求
如样例:
0 -2 -7 0

9 2 -6 2
-4 1 -4 1
-1 8 0 -2
假如在第一行到第三行之间求每一列的和那就是
-13 1 -17 3
这个序列的最大连续区间的和就是举行的高为1-3行之间的最大矩形里的和
那么我们就只需要枚举所有行的区间就行了,连续区间最大和的球阀复杂度是O(n),枚举所有行是O(n^2),所以总的复杂度就是O(n^3)。n<=100所以不会超时

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define MAX(a,b) (a) > (b)? (a):(b)
#define MIN(a,b) (a) < (b)? (a):(b)
#define mem(a) memset(a,0,sizeof(a))
#define INF 1000000007
#define MAXN 105
#define MAXC 1005
using namespace std;

int N,ma[105][105];
int sumU[105][105],sum[105];
int main()
{
    while(~scanf("%d",&N))
    {
        mem(sumU);
        int i,j,ans = -INF;
        for(i=1;i<=N;i++)for(j=1;j<=N;j++)
        {
            scanf("%d",&ma[i][j]);
            sumU[i][j]=sumU[i-1][j]+ma[i][j];
        }
        int Top,Down;
        for(Top=0;Top<N;Top++)
        {
            for(Down=Top+1;Down<=N;Down++)
            {
                mem(sum);
                int min, max = -INF;
                min = sumU[Down][1]-sumU[Top][1];//(sumU[Down][1]-sumU[Top][1])>0?0:(sumU[Down][1]-sumU[Top][1]);
                for(i=2;i<=N;i++)
                {
                    if(min<0)min=(sumU[Down][i]-sumU[Top][i]);
                    else min+=(sumU[Down][i]-sumU[Top][i]);
                    if(max<min)max=min;
                }
                ans=MAX(ans,max);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2013-08-14 11:11  龙城星  阅读(218)  评论(0编辑  收藏  举报