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; }