前缀和
一维前缀和
#include<stdio.h>
int main(){
int n=0,i=0,sum=0;
scanf("%d",&n);
int a[n];
int s[n];
for(i=0;i<n;i++){
scanf("%d",&a[i]);
s[i+1]=s[i]+a[i];
}
int t=0;
scanf("%d",&t);
int l[t],r[t];
for(i=0;i<t;i++){
scanf("%d %d",&l[i],&r[i]);
}
for(i=0;i<t;i++){
sum=s[r[i]]-s[l[i]];
printf("%d\n",sum);//求第l项到第r项的和
}
return 0;
}
用s数组表示a数组的数据的和再用s相减得出a数组的和
二维前缀和
#include<stdio.h>
int main() {
int n,a[125][125]={0},s[125][125]={0};
int i,j,x,y,max,ans=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
scanf("%d",&a[i][j]);
s[i][j]=a[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
}
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
for(x=0;x<=n-i;x++){
for(y=0;y<=n-j;y++){
ans=s[x][y]-s[x+i][y]-s[x][y+j]+s[x+i][y+j];
if(ans>max) max=ans;
}
}
}
}
printf("%d",max);
return 0;
}
上面代码是从n*n的矩阵中找出最小的矩阵和
图中s4为任意矩阵和公式推导的结果,通过
s[i][j]=a[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
求出发点为a11结束点为snn的矩阵和
再通过
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
for(x=0;x<=n-i;x++){
for(y=0;y<=n-j;y++){
ans=s[x][y]-s[x+i][y]-s[x][y+j]+s[x+i][y+j];
if(ans>max) max=ans;
}
}
}
}
x和y给出不同的矩阵大小,i和j控制x和y给出的矩阵不断移动,最后再求出最大值