洛谷P2706 巧克力

题目背景

王7的生日到了,他的弟弟准备送他巧克力。

题目描述

有一个被分成n*m格的巧克力盒,在(i,j)的位置上有a[i,j]块巧克力。就在送出它的前一天晚上,有老鼠夜袭巧克力盒,某些位置上被洗劫并且穿了洞。所以,你——王7的弟弟王9,必须从这个满目苍夷的盒子中切割出一个矩形巧克力盒,其中不能有被老鼠洗劫过的格子且使这个盒子里的巧克力尽量多。

输入输出格式

输入格式:

 

第一行有两个整数 n、m。第 i+1行的第 j 个数表示a[ i , j ]。如果这个数为 0 ,则表示这个位置的格子被洗劫过。

 

输出格式:

 

输出最大巧克力数。

 

输入输出样例

输入样例#1:
3 4
1 2 3 4
5 0 6 3
10 3 4 0
输出样例#1:
17
//10 3 4这个矩形的巧克力数最大

说明

1≤n,m≤300

0≤a[i,j]≤255

 

题目大意:求不含0的最大子矩形的权值和

题解:

二维前缀和暴力50

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 100000000
using namespace std;

int ans,n,m,map[310][310],sum[310][310];

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&map[i][j]);
            if(!map[i][j])map[i][j]=-inf;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+map[i][j];
        }
    }
    for(register int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(register int chang=1;chang+j-1<=m;chang++){
                for(int kuan=1;kuan+i-1<=n;kuan++){
                    int x=i+kuan-1,y=j+chang-1;
                    int gg=sum[x][y]-sum[i-1][y]-sum[x][j-1]+sum[i-1][j-1];
                    if(gg>ans)ans=gg;
                }
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

正解:预处理每列的前缀和 然后枚举子矩形的上下边界 更新答案

 

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1000000
using namespace std;

int ans,n,m,sum[310][310];

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&sum[i][j]);
            if(!sum[i][j])sum[i][j]=-inf;
            sum[i][j]+=sum[i-1][j];
        }
    }
    for(int tu=0;tu<n;tu++){
        for(int dn=tu+1;dn<=n;dn++){
            int cnt=0;
            for(int i=1;i<=m;i++){
                if(cnt<0)cnt=sum[dn][i]-sum[tu][i];
                else cnt+=sum[dn][i]-sum[tu][i];
                ans=max(ans,cnt);
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/zzyh/p/7651833.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值