标签:赋值 marked btn 子矩阵 namespace har 巧克力 NPU inpu
王7的生日到了,他的弟弟准备送他巧克力。
有一个被分成n*m格的巧克力盒,在(i,j)的位置上有a[i,j]块巧克力。就在送出它的前一天晚上,有老鼠夜袭巧克力盒,某些位置上被洗劫并且穿了洞。所以,你——王7的弟弟王八王9,必须从这个满目苍夷的盒子中切割出一个矩形巧克力盒,其中不能有被老鼠洗劫过的格子且使这个盒子里的巧克力尽量多。
第一行有两个整数 n、m。第 i+1行的第 j 个数表示a[ i , j ]。如果这个数为 0 ,则表示这个位置的格子被洗劫过。
输出最大巧克力数。
3 4 1 2 3 4 5 0 6 3 10 3 4 0
17 //10 3 4这个矩形的巧克力数最大
1≤n,m≤300
0≤a[i,j]≤255
整体的思路是建一个2维的数组,
首先0的位置不可选择,所以赋值为-inf,问题就变成最大子矩阵了
这个可以前缀和啦
我们可以枚举一个行数,在枚举另一个行数,来表示矩阵的上下,然后中间的每一个点都必须要选择,所以可以纵向压缩成一个点
虽然是一个N^3的算法但我还是骗了83分(能拿分的算法就是好算法)
尽管有人说把快读去掉就能A。。。。。。
#include<cstdio> #include<iostream> #define inf 1<<25 #define ll long long using namespace std; ll n,m; ll map[310][310],s[310],up[310][310]; ll ans; int i,j,k; inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){ if(ch==‘-‘){ w=-1; } ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘){ s=s*10+ch-‘0‘; ch=getchar(); } return s*w; } int main(){ n=read(); m=read(); for(i=1;i<=n;++i){ for(j=1;j<=m;++j){ map[i][j]=read(); if(!map[i][j]){ map[i][j]=-inf; } up[i][j]=up[i-1][j]+map[i][j]; } } for(i=1;i<=n;++i){ for(j=i;j<=n;++j){ ll mi=0; for(k=1;k<=m;++k){ s[k]=s[k-1]+up[j][k]-up[i-1][k]; } for(k=1;k<=m;++k){ ans=max(ans,s[k]-mi); mi=min(s[k],mi); } } } printf("%lld\n",ans); return 0; }
标签:赋值 marked btn 子矩阵 namespace har 巧克力 NPU inpu
原文地址:https://www.cnblogs.com/hrj1/p/11717332.html