这是一道比较基础的子序列的问题,当然了,数据是比较大的如果直接暴力的话就会TEL的,所以还需要讲究一点策略。这个前面也已经出现过不少吧。这个问题就相当于DP里面的另一类问题状态压缩。这个想法是一样的他要求的的就是一个x*y的矩阵,那么我们就是先将需要求得矩阵的个边的和都求出来。我们所说的矩阵X*Y的意识就是有x行y列,并不是说可以调换来。当然这里的话我们采用横向和纵向相加的做法是一样的,最后的结果也是一样的,我这里就是横向相加。这样的话,就可以减少一个数量级的计算。所以就可以飘过不至于TEL。这个相加之后的结果处理就是自己需要考虑的的事情只要你自己不想错就可以做出来。说到这里也基本有了一个思路,知道思路之后大家下面就应该自己思考了。但是下面还是给一个AC的代码仅供参考:
#include<iostream> using namespace std; #include<cstdlib> const int Max=1002; int a[Max][Max]; int b[Max][Max]; int c[Max][Max]; int main() { int T; int i,j,k,num; cin>>T; int m,n,x,y; int i1,j1; int i2,j2; while(T--) { i1=j1=0; k=0; num=0; scanf("%d%d%d%d",&m,&n,&x,&y); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); memset(a,0,sizeof(a)); for(i=0;i<m;i++) for(j=0;j<n;j++) { scanf("%d",&a[i][j]); b[i][j]=a[i][j]; c[i][j]=a[i][j]; } for(i=1;i<m;i++) for(j=0;j<n;j++) { b[i][j]+=b[i-1][j];//表示行的相加; } for(j=0;j<=n-y;j++) for(i=x-1;i<m;i++) { num=0; i1=0; j1=0; if(i==x-1) { for(j2=j;j2<j+y;j2++) i1+=b[i][j2]; num=i1; } else { for(j2=j;j2<j+y;j2++) { i1+=b[i][j2]; j1+=b[i-x][j2]; } num=i1-j1; } if(num>k) k=num; } cout<<k<<endl; } return 0; }