• 洛谷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
    ",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
    ",ans);
        return 0;
    }
  • 相关阅读:
    Django实现组合搜索的方法示例
    MySQL一些常用命令
    Linux IPMI 安装配置实用[转载]
    注意力训练的十个方法(转来的,原著者,不要打我)
    0001:Web与Web框架
    第二天Python
    第一天Python
    那些被疯狂追求的女孩,后来怎么样了?
    Linux服务器---流量监控MRTG
    Linux基础命令---文本编辑ex
  • 原文地址:https://www.cnblogs.com/zzyh/p/7651833.html
Copyright © 2020-2023  润新知