hdu 3855 單調棧
阿新 • • 發佈:2019-01-03
#include <iostream> #include <stdio.h> #include <memory.h> using namespace std; const int N=1010; //dp->1,1到i,j的所有和,,,,pre->i,j的同行的最近的比K小的點+1 int da[N][N],dp[N][N],pre[N][N]; int sum(int i,int j,int x,int y)//求矩形的面積 { return dp[x][y]-dp[i-1][y]-dp[x][j-1]+dp[i-1][j-1]; } struct node { int i,j,num;//行, 列, 次數 node(int x,int y,int n) { i=x; j=y; num=n; } node(){} }q[N]; int main() { int n,m,k,tt; for(scanf("%d",&tt);tt--;) { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) { int c=1; for(int j=1;j<=m;j++) { scanf("%d",&da[i][j]); if(da[i][j]<k) c=j+1; pre[i][j]=c; dp[i][j]=dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1]+da[i][j]; } } int ans=0; for(int j=1;j<=m;j++)//列舉最右的列 { int tl=0,now=0;//now for(int i=1;i<=n;i++)//從上至下 { if(da[i][j]<k)//清空 { tl=now=0; continue; } int c=pre[i][j]; int num=0; while(tl&&q[tl].j<=c)//把比當前長的都截掉,,,截掉之後都一樣長了,,所以只需要記錄個數 { now-=sum(q[tl].i-q[tl].num+1,q[tl].j,q[tl].i,c-1); num+=q[tl].num; tl--; } q[++tl]=node(i,c,1+num);//加上當前的 now+=sum(i,c,i,j);//更新 ans=max(ans,now); } } printf("%d\n",ans); } return 0; }