标签:
题目大意:
分析:
AC code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 189;
int n, m;
int g[MAXN][MAXN];
int rm[MAXN][MAXN];
int minr[MAXN][MAXN];
struct data
{
int c, p1, p2, p3, p4, l1, l2, l3, s;
data(int c=0, int p1=0, int p2=0, int p3=0, int p4=0, int l1=0, int l2=0, int l3=0, int s=0):c(c),p1(p1),p2(p2),p3(p3),p4(p4),l1(l1),l2(l2),l3(l3),s(s){}
}ans;
struct data2
{
int p, l, s;
data2(int p=0, int l=0, int s=0):p(p),l(l),s(s){}
void init() {p = l = s = 0;}
};
data2 maxu[MAXN][MAXN];
data2 maxd[MAXN][MAXN];
data2 maxu2[MAXN][MAXN];
data2 maxd2[MAXN][MAXN];
void work_rm()
{
for(int j = m; j >= 1; --j)
for(int i = 1; i <= n; ++i)
if(!g[i][j])
rm[i][j] = rm[i][j+1]+1;
}
void work_minr(int j)
{
for(int i = 1; i <= n; ++i)
{
minr[i][i] = rm[i][j];
for(int k = i+1; k <= n; ++k)
minr[i][k] = min(minr[i][k-1], rm[k][j]);
}
}
void work_maxu()
{
for(int i = 1; i <= n; ++i)
{
maxu[i][i] = data2(i, minr[i][i], minr[i][i]);
for(int k = i-1; k >= 1; --k)
if(maxu[i][k+1].s > (i-k+1)*minr[k][i])
maxu[i][k] = maxu[i][k+1];
else maxu[i][k] = data2(k, minr[k][i], (i-k+1)*minr[k][i]);
}
}
void work_maxd()
{
for(int i = n; i >= 1; --i)
{
maxd[i][i] = data2(i, minr[i][i], minr[i][i]);
for(int k = i+1; k <= n; ++k)
if(maxd[i][k-1].s > (k-i+1)*minr[i][k])
maxd[i][k] = maxd[i][k-1];
else maxd[i][k] = data2(k, minr[i][k], (k-i+1)*minr[i][k]);
}
}
void work_maxu2()
{
for(int i = 1; i <= n; ++i)
{
int u = i;
for(int j = m; j >= 1; --j)
{
maxu2[i][j].init();
u = min(i, u);
while(u && minr[u][i] > j) u--;
u++;if(u > i) continue;
maxu2[i][j] = maxu[i][u];
}
}
}
void work_maxd2()
{
for(int i = n; i >= 1; --i)
{
int d = i;
for(int j = m; j >= 1; --j)
{
maxd2[i][j].init();
d = max(i, d);
while(d <= n && minr[i][d] > j) d++;
d--;if(d < i) continue;
maxd2[i][j] = maxd[i][d];
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
scanf("%d", &g[i][j]);
work_rm();
for(int j = 1; j <= m; ++j)
{
work_minr(j), work_maxu(), work_maxd();
for(int p = 2; p <= n-1; ++p)
{
int u = p-1, d = p+1;
for(int q = p; q <= n-1 && minr[p][q]; ++q)
{
u = min(p-1, u), d = max(q+1, d);
while(u && minr[u][p-1] > minr[p][q]) u--;u++;if(u >= p) continue;
while(d <= n && minr[q+1][d] > minr[p][q]) d++;d--;if(d <= q) continue;
if(ans.s < (q-p+1)*minr[p][q]+maxu[p-1][u].s+maxd[q+1][d].s)
ans = data(j, maxu[p-1][u].p, p, q+1, maxd[q+1][d].p, maxu[p-1][u].l, minr[p][q], maxd[q+1][d].l, (q-p+1)*minr[p][q]+maxu[p-1][u].s+maxd[q+1][d].s);
}
}
work_maxu2(), work_maxd2();
for(int p = 2; p <= n-1; ++p)
if(minr[p][p] > 1)
for(int q = 1; q < minr[p][p]; ++q)
if(maxu2[p-1][q].s && maxd2[p+1][q].s && ans.s < q+maxu2[p-1][q].s+maxd2[p+1][q].s)
ans = data(j, maxu2[p-1][q].p, p, p+1, maxd2[p+1][q].p, maxu2[p-1][q].l, q, maxd2[p+1][q].l, q+maxu2[p-1][q].s+maxd2[p+1][q].s);
}
for(int i = ans.p1; i < ans.p2; ++i)
for(int j = 1; j <= ans.l1; ++j)
g[i][ans.c+j-1] = 8;
for(int i = ans.p2; i < ans.p3; ++i)
for(int j = 1; j <= ans.l2; ++j)
g[i][ans.c+j-1] = 8;
for(int i = ans.p3; i <= ans.p4; ++i)
for(int j = 1; j <= ans.l3; ++j)
g[i][ans.c+j-1] = 8;
if(ans.s)
{
printf("%d\n", ans.s);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
printf("%d", g[i][j]);
if(j < m) printf(" ");
}
puts("");
}
}
else puts("-1");
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
sgu250:Constructive Plan(单调性乱搞)
标签:
原文地址:http://blog.csdn.net/qq_20118433/article/details/46351421