BZOJ 3128 Usaco2013 Open Figure Eight

来源:互联网 发布:287团淘宝兼职是真的吗 编辑:程序博客网 时间:2024/06/05 04:40

题目大意:给定一个有坏点的矩阵,求能画出来的最大的“8”字形

“8”字形满足:

*数字8由上下两个矩形构成。
*数字8的上下两个矩形都满足至少有一个单元格在矩形内部。
*数字8顶部的矩形的底边必须为底部矩形顶边的子集。
*数字8只能刻在大理石完美无瑕的部分。
*规定数字8的得分为上矩形和下矩形的面积的乘积,它们希望得分能达到最大。

枚举顶部矩形的底边,可以用上一行的底边O(1)转移得到,然后每行O(n^2)向左右拓展

然后枚举底部矩形的顶边,可以用下一行的顶边O(1)转移得到,顶部矩形的最大面积已求出,O(1)更新答案

最终时间复杂度O(n^3) 小心内存

尼玛考试时无解判挂丢了10分。。。简直。。。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 302using namespace std;int n;long long ans=-1;char map[M][M];int sum[M][M];int f[M][M][M],g[M][M][M];int Get_Sum(int x1,int y1,int x2,int y2){return sum[x2][y2]+sum[x1-1][y1-1]-sum[x2][y1-1]-sum[x1-1][y2];}int main(){freopen("eight.in","r",stdin);freopen("eight.out","w",stdout);int i,j,k;cin>>n;for(i=1;i<=n;i++)scanf("%s",map[i]+1);for(i=1;i<=n;i++)for(j=1;j<=n;j++)sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+(map[i][j]=='*');for(i=1;i<=n-2;i++)for(j=i+2;j<=n;j++){int last=0;for(k=1;k<=n;k++){if(map[k][i]=='*'||map[k][j]=='*')last=0;if(!Get_Sum(k,i,k,j)){if(last)f[k][i][j]=(k-last-1)*(j-i-1);elselast=k;}}last=0;for(k=n;k;k--){if(map[k][i]=='*'||map[k][j]=='*')last=0;if(!Get_Sum(k,i,k,j)){if(last)g[k][i][j]=(last-k-1)*(j-i-1);elselast=k;}}}for(i=1;i<=n;i++){for(j=1;j<=n-3;j++)for(k=j+3;k<=n;k++){if(Get_Sum(i,j,i,k))break;f[i][j][k]=max(f[i][j][k],f[i][j][k-1]);}for(j=n;j>=4;j--)for(k=j-3;k;k--){if(Get_Sum(i,k,i,j))break;f[i][k][j]=max(f[i][k][j],f[i][k+1][j]);}}for(i=3;i<=n-2;i++)for(j=1;j<=n-2;j++)for(k=j+2;k<=n;k++)if(!Get_Sum(i,j,i,k))ans=max(ans,(long long)f[i][j][k]*g[i][j][k]);cout<<ans<<endl;}//あぁ 花火が夜空 綺麗に咲いて ちょっと切なく//あぁ 風が時間と ともに流れる


0 0
原创粉丝点击