BZOJ 3873: [Ahoi2014]拼图

标签(空格分隔): OI-BZOJ OI-DP


Time Limit: 10 Sec

Memory Limit: 256 MB


Description

JYY最近迷上了拼图游戏。作为一个计算机科学家,JYY有一套黑白色的拼图,他希望通过合理的拼接,使得拼出的最终图案中,能包含面积最大的全白色子矩形。JYY一共有S块拼图,并且由1到S编号。编号为i的拼图是一个N行列的方格矩形,每个方格都为黑色或者白色。一开始JYY将他的这S块拼图按照编号顺序左右相连依次放在桌上拼成了一个N行M列(这里M=Sigma(Wi)(1<=i<=S)的大矩形。之后JYY发现,可以通过改变这S块拼图的连接次序,使得拼成的N行M列的大矩形中,最大全白子矩形面积变大。现在JYY想知道,怎么拼才能得到最大的全白子矩形呢?请你帮助他计算出最佳的拼接方案。

Input

每个输入文件中包含多组测试数据。输入文件第一行包含一个整数T,代表

测试数据的组数,接下来按顺序描述了每组测试数据。

每组测试数据的第一行包含两个整数S和N。

接下来S组输入,第i组对应编号为i的拼图。

在第i组输入中,第一行包含一个整数;

接下来N行描述一个N行列的0/1矩形;

其中第x行y列为0则表示该拼图对应位置的颜色是白色,反之则为黑色。

Output

对于每组数据输出一行包含一个整数ans,表示最大可能的全白色子矩形的面积。

Sample Input

1

34

4

1001

0000

0010

1001

3

000

010

000

011

2

00

10

01

00

Sample Output

6

HINT

对于100%的数据满足1<=S,N,Wi<=105,N*Sigma(Wi)<=105,T<=3

添加数组一组--2015.02.28


Solution####

设\(m=\sum\limits_{i=1}^S{w_i}\)

算法1:枚举矩形上下边界,每个块作为左端块,右端块,中间块分别考虑。

对于在某个块内部的矩形求一下最大连续0的个数即可,复杂度\(O(n*n*m)\)

算法2:求出每个点往上延伸的最大长度,枚举每个点作为矩形的下边界上的点,向上延伸的极限作为矩形的下边界,可以\(O(m)\)求出答案。对于这个算法的正确性可以朴素的理解:对于相同左右边界的矩形肯定尽量向上延伸,上边界会被某个东西挡住。这个方案在枚举到,被挡住位置的正下方所对应下边界上的位置的时候,会被包含入答案。复杂度\(O(n*m*m)\)

当\(n<\sqrt{n*m}\)时使用算法1,否则使用算法2


Code####

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<bitset>
#include<vector>
using namespace std;
#define LL long long
int read()
{
int s=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
return s*f;
}
int read2()
{
int s=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';break;ch=getchar();}
return s*f;
}
//smile please
int T,S,N,w[100005],ans;
bitset<100005> sa[405],pa;
int rr[405];
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
for(T=read();T--;)
{S=read();N=read();ans=0;
if(N<=300)
{
for(int i=1;i<=S;i++)
{w[i]=read()+w[i-1];
for(int j=1;j<=N;j++)
for(int k=w[i-1]+1;k<=w[i];k++)
sa[j][k]=read2();
}
for(int i=1;i<=N;i++)
{pa=sa[i];
for(int j=i;j<=N;j++)
{pa|=sa[j];
int sum=0,sum2=0;
int l1=0,lw1=0,l2=0;
int r1=0,rw1=0,r2=0;
for(int k=1;k<=w[S];k++)
sum=(pa[k]?0:sum+1),
ans=max(ans,(j-i+1)*sum);
for(int k=1;k<=S;k++)
{sum=0;
for(int l=w[k-1]+1;l<=w[k]&&!pa[l];l++)
sum++;
if(sum==w[k]-w[k-1])
{sum2+=w[k]-w[k-1];continue;}
if(sum>l1)
l2=l1,l1=sum,lw1=k;
else
if(sum>l2)
l2=sum;
sum=0;
for(int l=w[k];l>=w[k-1]+1&&!pa[l];l--)
sum++;
if(sum>r1)
r2=r1,r1=sum,rw1=k;
else
if(sum>r2)
r2=sum;
}
ans=max(ans,((lw1==rw1?max(l1+r2,l2+r1):l1+r1)+sum2)*(j-i+1));
}
}
}
else
{
for(int i=1;i<=S;i++)
{w[i]=read()+w[i-1];
for(int j=1;j<=N;j++)
for(int k=w[i-1]+1;k<=w[i];k++)
sa[k][j]=read2();
}
for(int j=1;j<=w[S];j++)
rr[j]=0;
for(int i=N;i>=1;i--)
{for(int j=1;j<=w[S];j++)
rr[j]=(sa[j][i]?0:rr[j]+1);
for(int j=1;j<=w[S];j++)
{int sum=0,sum2=0;
int l1=0,lw1=0,l2=0;
int r1=0,rw1=0,r2=0;
for(int k=1;k<=w[S];k++)
sum=(rr[k]<rr[j]?0:sum+1),
ans=max(ans,rr[j]*sum);
for(int k=1;k<=S;k++)
{sum=0;
for(int l=w[k-1]+1;l<=w[k]&&rr[l]>=rr[j];l++)
sum++;
if(sum==w[k]-w[k-1])
{sum2+=w[k]-w[k-1];continue;}
if(sum>l1)
l2=l1,l1=sum,lw1=k;
else
if(sum>l2)
l2=sum;
sum=0;
for(int l=w[k];l>=w[k-1]+1&&rr[l]>=rr[j];l--)
sum++;
if(sum>r1)
r2=r1,r1=sum,rw1=k;
else
if(sum>r2)
r2=sum;
}
ans=max(ans,((lw1==rw1?max(l1+r2,l2+r1):l1+r1)+sum2)*rr[j]);
}
}
}
printf("%d\n",ans);
}
//fclose(stdin);
//fclose(stdout);
return 0;
}

BZOJ 3873: [Ahoi2014]拼图的更多相关文章

  1. BZOJ 3878: [Ahoi2014]奇怪的计算器

    BZOJ 3878: [Ahoi2014]奇怪的计算器 标签(空格分隔): OI-BZOJ OI-线段树 Time Limit: 10 Sec Memory Limit: 256 MB Descrip ...

  2. Bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划 三分+贪心

    3874: [Ahoi2014&Jsoi2014]宅男计划 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 861  Solved: 336[Su ...

  3. BZOJ 3875: [Ahoi2014]骑士游戏 dp+spfa

    题目链接: 题目 3875: [Ahoi2014]骑士游戏 Time Limit: 30 Sec Memory Limit: 256 MB 问题描述 [故事背景] 长期的宅男生活中,JYY又挖掘出了一 ...

  4. bzoj 3876 [Ahoi2014]支线剧情(有上下界的最小费用流)

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 484  Solved: 296[Submit][Status ...

  5. BZOJ 3875: [Ahoi2014]骑士游戏

    d[i]表示消灭i所需的最小体力值, d[i] = min(S[i], K[i]+Σd[x]), Σd[x]表示普通攻击而产生的其他怪兽. 因为不是DAG, 所以用个队列类似SPFA来更新答案. -- ...

  6. bzoj 3874: [Ahoi2014]宅男计划

    Description  [故事背景] 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY 不得不依靠叫外卖来维持生计. [问题描述] 外卖店一共有N种食物,分别有1到N编号.第i种 ...

  7. BZOJ 3876: [Ahoi2014]支线剧情 [上下界费用流]

    3876: [Ahoi2014]支线剧情 题意:每次只能从1开始,每条边至少经过一次,有边权,求最小花费 裸上下界费用流...每条边下界为1就行了 注意要加上下界*边权 #include <io ...

  8. BZOJ 3875: [Ahoi2014]骑士游戏 spfa dp

    3875: [Ahoi2014]骑士游戏 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3875 Description [故事背景] 长 ...

  9. BZOJ 3876: [Ahoi2014]支线剧情 带下界的费用流

    3876: [Ahoi2014]支线剧情 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3876 Description [故事背景] 宅 ...

随机推荐

  1. 深入解析Android Design包——Behavior

    已经说过了,在AndroidDesign包中主要有两个核心概念:一是NestedScroll,另一个就是Behavior. 相比于NestedScroll这个概念来说,Behavior分析起来会难很多 ...

  2. PJzhang:英国通信总部GCHQ开源产品-网络瑞士军刀CyberChef

    猫宁!!! 参考链接:https://www.4hou.com/info/news/981.html 这个产品免费开源易用,如果称之为网络瑞士军刀,没什么异议. github地址:https://gi ...

  3. Unity---DOTween插件学习(2)---设置参数、Ease曲线、回调函数、动画控制函数

    目录 6.Set设置参数 7.Ease曲线 8.回调函数 9.动画控制函数 本文及系列参考于Andy老师的DOTween系列 欢迎大家关注Andy老师 6.Set设置参数 在Unity中添加一个Cub ...

  4. 我的省选 Day -12

    Day -12 今天是三月份的最后一天,春天真的也就走过了1/3了呢. 昨晚做了个神秘而悲伤的梦.(这样子写下来会不会不太好.. 我梦见欢洛了. 那是在新校区的门口,我看见他,然后向他跑过去,他转身对 ...

  5. 自定义标签报 无法为TAG [my2:hello]加载标记处理程序类[null]

    今天练习jsp自定义标签的时候,等我写好全部和检查万无一失的时候.执行然后报错了 无法为TAG [my2:hello]加载标记处理程序类[null] 我反复检查代码,发现代码也没什么问题.后面通过百度 ...

  6. Stream流、方法引用

    Stream流.方法引用 Stream流.方法引用 Stream流.方法引用 Stream流.方法引用 Stream流.方法引用 ... ...

  7. [转]深入探讨C语言中局部变量与全局变量的作用域与存储类别

    C语言中局部变量和全局变量变量的作用域与存储类别(auto,static,extern,register) 1.局部变量和全局变量在讨论函数的形参变量时曾经提到,形参变量只在被调用期间才分配内存单元, ...

  8. Linux Shell命令系列(5) VI编辑器

    vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版本,vi编辑器是完全相 ...

  9. Jenkins~通过WebDeploy实现自动部署

    Jenkins以之前的文章中已经有所介绍,主要集成了自动化部署的功能,而对于自动化部署来说是由多个组件组成的,每个组件负责自己的事,如今天说的webDeploy,它主要实现将网站文件动态发布到另一台I ...

  10. Oracle视图,索引,序列

    什么是视图[View] (1)视图是一种虚表 (2)视图建立在已有表的基础上, 视图赖以建立的这些表称为基表(3)向视图提供数据内容的语句为 SELECT 语句,可以将视图理解为存储起来的 SELEC ...