给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大。
int sum[N][N];
int a[N][N];
int main(){
int n,m;
int T;sf("%d",&T);
while(T--){
int x,y;
sf("%d%d%d%d",&n,&m,&x,&y);
mem(sum,0);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
sf("%d",&a[i][j]);
sum[i][j]=sum[i-1][j]+a[i][j];
}
}
int ans=0;
for(int i=x;i<=n;++i){
for(int j=y;j<=m;++j){
int tot=0;
for(int k=j-y+1;k<=j;++k){
tot+=sum[i][k]-sum[i-x][k];
}
ans=max(ans,tot);
}
}
pf("%d\n",ans);
}
}
网络赛的题目:
大佬代码…
心得:
另开一个dp[][]来记录有没有取,然后还有个minn就可以处理看有没有替换p 的状态..
int n,m,p;
int num[maxn][maxn];
int sum[maxn][maxn];
int dp[maxn][2];
int cnt[maxn];
int minn[maxn];
int total=0;
int main(){
while(~scanf("%d%d%d",&n,&m,&p)){
total=0;
int totalmin=inf;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&num[i][j]);
total+=num[i][j];
totalmin=min(totalmin,num[i][j]);
}
}
// for(int i=1;i<=m;i++){sum[i][0]=num[i][0];}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
sum[j][i]=sum[j][i-1]+num[i][j];//第j列前i行
}
}
int ans=-inf;
for(int i=1;i<=n;i++){
memset(minn,0x3f,sizeof(minn));
for(int j=i;j<=n;j++){
for(int k=1;k<=m;k++)cnt[k]=sum[k][j]-sum[k][i-1];
for(int k=1;k<=m;k++)minn[k]=min(minn[k],num[j][k]);
dp[0][0]=0;
for(int k=1;k<=m;k++){
dp[k][0]=max(cnt[k],dp[k-1][0]+cnt[k]);
dp[k][1]=max(cnt[k]+(p-minn[k]),dp[k-1][0]+cnt[k]+p-minn[k]);
if(k>1)dp[k][1]=max(dp[k][1],dp[k-1][1]+cnt[k]);
if(i==1&&j==n&&k==m){
ans=max(ans,dp[k][1]);
if(dp[k][0]!=total||(dp[k][0]==total&&p==totalmin)){
ans=max(dp[k][0],ans);
}
}
else{
ans=max(max(ans,dp[k][0]),dp[k][1]);
}
}
}
}
printf("%d\n",ans);
}
return 0;
}