[JZOJ2679] 跨时代
题目
题目大意
给你一堆边,你要将它们围成面积最大的矩形。
边不一定要用完,而且围成的矩形不能凸出一块。
\(n\leq 16\)
\(l_i \leq 15\)
思考历程
看到这题的第一眼,就会立马往DP方面去想。
我一开始的想法是求出每种选择的状态可以得到的长度,
然后就可以得出哪些状态可以得到两条长度一样的边。
接下来就开始匹配,找不相交的集合,如果两个都满足条件就统计入答案。
但是我又想,上面的最后一个操作会不会使时间崩掉?
于是我又想了几十分钟,迫不得已去打第三题和第二题了……
打完后回来,仔细想想,发现可以折半搜索!
把\(n\)条边拆成两组,每一条边有\(5\)种选择,分别为不选和加入\(a,b,c,d\)四条边。
用\(5^8\)的时间枚举左边,然后钦定\(a\leq c\)且\(b\leq d\)(如果不满足条件就踢掉,不用交换,因为交换后的情况是能够枚举到的)。我们以\((c-a,d-b)\)作为关键字存在某个表中(用hash或map或数组,怎样都可以)。
之所以存下它们的差,是因为在差相同的情况下,可以互补成完整的矩形。
对于每个出现过的关键字,都给它分配一个数组,存下\((a,b)\)
然后就是枚举右边的情况,搞完之后以同样的方式在表中找,如果关键字出现过,就在分配给它的数组中枚举,将\((a_i+c')(b_i+d')\)统计入答案中。
显然,最花时间的地方就是在数组中枚举,如果这个数组开得很大,有可能会拖慢速度。
我试了一个\(16\)个\(8\)的数据,就成功卡掉了。
于是我便想到,数组中的重复元素其实是很多的。所以我将vector
换成了set
,那个数据就跑得贼快了。
去掉了重复,我也不知道数据还有什么办法卡我,因为每个数组都不会特别大(根据数据范围感性地估计一下~)
于是我就交了上去。果然AC,而且还跑得比较快。
后来我又思考,万一数据真的卡我,该怎么办。于是我想到,同一个数组中若有\(a_i\leq a_j\)且\(b_i \leq b_j\),显然\((a_i,b_i)\)是可以不要的。那么在左边的枚举做完之后,我们将每个数组里的元素排序一遍,把其中这些没有意义的元素删去。于是我们就可以得到一个\(a_i\)递增,\(b_i\)递减的一个东西。显然我们要让\(a_id'+b_ic'\)最大,就可以在数组上二分(或三分?)来做。反正时间复杂度是绝对可以保证的。
正解
其实这道题的方法有很多很多……折半搜索只是冰山一角。
事实上我一开始想的、但却没有打的方法是对的。
有的人直接搜索就过了,有的人背包、状压……
所以就不一一说明了……
于是“正解”这一栏有什么意义?
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
int n,m;
int len[17];
#define mo 1000007
struct Node{
int key,num;
} h[mo];
inline int my_hash(int ia1,int ia2){
int key=ia1*997+ia2+mo,i=key%mo;
for (;h[i].key!=key && h[i].key;i=(i+1==mo?0:i+1));
return i;
}
int cnt;
set<pair<int,int> > arr[15000];
void dfs1(int k,int a,int b,int c,int d){
if (k>m){
if (a>b || c>d)
return;
int w=my_hash(b-a,d-c);
if (!h[w].num)
h[w].num=++cnt;
arr[h[w].num].insert(make_pair(a,c));
return;
}
dfs1(k+1,a,b,c,d);
dfs1(k+1,a+len[k],b,c,d);
dfs1(k+1,a,b+len[k],c,d);
dfs1(k+1,a,b,c+len[k],d);
dfs1(k+1,a,b,c,d+len[k]);
}
int ans=0;
void dfs2(int k,int a,int b,int c,int d){
if (k>n){
if (a>b || c>d)
return;
int w=my_hash(b-a,d-c);
if (h[w].num){
for (set<pair<int,int> >::iterator p=arr[h[w].num].begin();p!=arr[h[w].num].end();++p)
ans=max(ans,(b+p->first)*(d+p->second));
}
return;
}
dfs2(k+1,a,b,c,d);
dfs2(k+1,a+len[k],b,c,d);
dfs2(k+1,a,b+len[k],c,d);
dfs2(k+1,a,b,c+len[k],d);
dfs2(k+1,a,b,c,d+len[k]);
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&len[i]);
m=n>>1;
dfs1(1,0,0,0,0);
dfs2(m+1,0,0,0,0);
if (ans)
printf("%d\n",ans);
else
printf("No Solution\n");
return 0;
}
总结
做题的时候不要怂,有时暴力的方法照样能过!
[JZOJ2679] 跨时代的更多相关文章
- 【JZOJ2679】跨时代
description 钟逆时针而绕,恶物狰狞的倾巢,我谦卑安静地于城堡下的晚祷,压抑远古流窜的蛮荒暗号,而管风琴键高傲的说,那只是在徒劳.我的乐器在环绕,时代无法淘汰我霸气的皇朝. 你无法预言,因为 ...
- 跨时代的分布式数据库 – 阿里云DRDS详解(转)
原文章地址:https://www.csdn.net/article/a/2015-08-28/15827676 跨时代的分布式数据库 – 阿里云DRDS详解 发表于2015-08-28 18:39| ...
- 跨时代的MySQL8.0新特性解读
目录 MySQL发展历程 MySQL8.0新特性 秒级加列 性能提升 文档数据库 SQL增强 共用表表达式(CTEs) 不可见索引(Invisible Indexes) 降序索引(Descending ...
- APP技术演化的路
谈起APP,大家都太熟悉不过了,今天想谈谈这么多年技术演化的路. 早期一些大公司就开始做一些APP了,例如facebook.google等国外的公司就已经开发这个技术路线,那个时候的APP数量很少,基 ...
- 解读ASP.NET 5 & MVC6系列(1):ASP.NET 5简介
ASP.NET 5简介 ASP.NET 5是一个跨时代的改写,所有的功能和模块都进行了独立拆分,做到了彻底解耦.为了这些改写,微软也是蛮 拼的,几乎把.NET Framwrok全部改写了一遍,形成了一 ...
- ASP.Net WebForm温故知新学习笔记:一、aspx与服务器控件探秘
开篇:毫无疑问,ASP.Net WebForm是微软推出的一个跨时代的Web开发模式,它将WinForm开发模式的快捷便利的优点移植到了Web开发上,我们只要学会三步:拖控件→设属性→绑事件,便可以行 ...
- [.net 面向对象程序设计深入](4)MVC 6 —— 谈谈MVC的版本变迁及新版本6.0发展方向
[.net 面向对象程序设计深入](4)MVC 6 ——谈谈MVC的版本变迁及新版本6.0发展方向 1.关于MVC 在本篇中不再详细介绍MVC的基础概念,这些东西百度要比我写的全面多了,MVC从1.0 ...
- 【转】解读ASP.NET 5 & MVC6系列(1):ASP.NET 5简介
ASP.NET 5是一个跨时代的改写,所有的功能和模块都进行了独立拆分,做到了彻底解耦.为了这些改写,微软也是蛮 拼的,几乎把.NET Framwrok全部改写了一遍,形成了一个.NET Core的东 ...
- 手把手写一个html_json信息源
html_json用于从网页里提取json数据. 这里用新浪读书的书讯举个例子,手把手写一个html_json信息源. 打开新浪读书的首页,可以看到页面下方有最新.书讯.童书.小说等几个Tab,这里我 ...
随机推荐
- Python匿名函数(lambda函数)
匿名函数 -- 一行函数 lambda -- 关键字 x是普通函数的形参(位置,关键字...)可以不接收参数(x可以不写) :x是普通函数的函数值(只能返回一个数据类型)(:x返回值必须写) 1)此函 ...
- lca 倍增模版
; void dfs(int u,int fa){ d[u]=d[fa]+; p[u][]=fa; ;i<POW;i++) p[u][i]=p[p[u][i-]][i-]; int sz=edg ...
- 【HDUOJ】1257 最少拦截系统
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257 题意:经典题. 题解:最长上升子序列. 代码: #include <iostream> ...
- Mac版本的 Axure rp8 不显示菜单栏
我之前也是一直在找这个问题,可能mac用的不熟练吧,其实他的菜单栏就近在眼前 你看不见只是因为你的关注点在axure上 往大了看,他的菜单栏显示在你的电脑的菜单栏上,mac的菜单栏基本都是这么显示的, ...
- python异常整理
一.操作excel 时异常 1.PermissionError: [Errno 13] Permission denied (1)原因:权限错误:[Errno 13] 权限被拒绝 错误产生的原因是文件 ...
- BeanFactory 和 ApplicationContext 区别
区别 BeanFactory: Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能 BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean ...
- delphi 获取本机IP地址和MAC地址 (转)
unit NetFunc; interface uses SysUtils, Windows, dialogs, winsock, Classes, ComObj, WinInet, Variants ...
- 数学相关比较 牛顿迭代法求开方 很多个n的平方分之一
牛顿迭代法求开方 牛顿迭代法 作用: 求f(x) = 0 的解 方法:假设任意一点 x0, 求切线与x轴交点坐标x1, 再求切线与x轴交点坐标x2,一直重复,直到f(xn) 与0的差距在一个极小的范围 ...
- 暴力”注入Explorer
暴力"注入Explorer pjf(jfpan20000@sina.com) 向一个运行中的进程注入自己的代码,最自然莫过于使用Cr ...
- Delphi常用字符串函数
Delphi常用字符串函数 一.字符转换函数1.ord(input[i])返回字符表达式 input 左端起第 I 字符的ASCII 码值.2.CHAR()将ASCII 码转换为字符.如果没有输入 ...