洛谷——P2706 巧克力

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

 

 

 for四次方枚举矩形的起始节点以及矩形的长宽,然后连T带Wa

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 500
using namespace std;
int n,m,s,x,y,a[N][N],sum[N][N],v1[N],v2[N],ans;
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
     {
         a[i][j]=read();
         if(!a[i][j])
          v1[i]+=1,v2[j]+=1;
        sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
      } 
    for(int l1=0;l1<n;l1++)
      for(int l2=0;l2<m;l2++)
        for(int i=0;i<=n-l1+1;i++)
           if(v1[i+l1]-v1[i]==0)
           for(int j=0;j<=m-l2+1;j++)
             if(v2[j+l2]-v2[j]==0)
              {
                  x=i+l1,y=j+l2;
                  ans=max(ans,sum[x][y]-sum[x][j]-sum[i][y]+sum[i][j]);
              }    
    printf("%d",ans);
    return 0;
}
智障的33分代码

 

预处理出每一行的前缀和,然后暴力枚举矩形的上边界以及下边界,然后在枚举列,每当统计出的s出现负值,则说明出现了被吃掉的巧克力,更新s为0,然后在继续枚举。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 500
#define maxn 0x7fffffff
using namespace std;
long long n,m,s,x,y,a[N][N],sum[N][N],v1[N],v2[N],ans;
int main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
     {
         scanf("%lld",&a[i][j]);
         if(!a[i][j])
          a[i][j]=-maxn;
        sum[i][j]+=sum[i-1][j]+a[i][j];
      } 
    for(int i=0;i<n;i++)
     for(int j=i+1;j<=n;j++)
     {
         for(int k=1;k<=m;k++)
         {
             s+=sum[j][k]-sum[i][k];
             if(s<0) s=0;
             ans=max(ans,s);
           }  
        s=0;
      } 
    printf("%lld",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/z360/p/7608115.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值