【Foreign】咏叹 [模拟退火]
咏叹
Time Limit: 100 Sec Memory Limit: 256 MB
Description
有n根木棍,第i根长度为ai。你要贴着墙围出一个矩形区域,木棍围成的矩形边缘必须平行或垂直于墙,且又一边必须利用墙。你可以把至多1根木棍劈成两根(不一定要在整数位置)。最大化矩形面积。
Input
包含多组数据。每组数据第一行一个整数n,第二行n个整数ai。
Output
输出面积最大的矩形与墙壁平行的那条边的长度(显然是一个整数),若有多个最优解输出与墙壁平行的那条边最长的。
Sample Input
3
3 3 3
4
4 4 4 4
Sample Output
6
8
HINT
对于10%的数据,n=2。
对于30%的数据,n<=15。
对于50%的数据,n<=32。
对于另外20%的数据,ai<=100。
对于100%的数据,2<=n<=40,1<=ai<=10^9,数据不超过10组。
Solution
首先,必然是全部木棍都用上的时候最优,对于n=2的时候,显然就是分三种情况讨论一下就好了。
然后我们从n=2的情况拓展。发现,其实可以把多个木棍并在一起,使其变为n=2的情况,然后讨论。那么现在答案只和两段的长度有关了。
但是直接暴力搜索是O(2^40)的,显然不行,我们考虑分为两部分来搜索,搜索前n/2个,和后n/2个,表示选不选得到的价值,现在效率是O(2*2^20)。
然后怎么得到答案呢?显然:如果我们设宽为x,则长为tot-2x(tot为总长),那么这是一个二次函数,必然有峰值。
所以我们大胆猜测,我们确定了一半,另外一半使得其答案最优的话也可能满足有峰值的性质。
然后我们固定一半,另一半运用模拟退火求解即可!
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
using namespace std;
typedef long long s64; const int ONE = ; int T,n;
int a[],top1,top2;
s64 Stk1[ONE],Stk2[ONE];
s64 Square, Ans, tot, RE; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} s64 Get(s64 width,s64 length)
{
s64 res = length * width; if(res > Square || (res==Square && length>Ans))
Square = res, Ans = length;
return res;
} s64 Check(s64 A,s64 B)
{
if(A > B) swap(A,B);
s64 res = ;
res = max(res,Get(A, B-A));
res = max(res,Get(A/,B));
res = max(res,Get(B/,A));
return res;
} void Dfs1(s64 val,int T)
{
if(T>n/) {Stk1[++top1] = val; return;}
Dfs1(val,T+); Dfs1(val+a[T],T+);
} void Dfs2(s64 val,int T)
{
if(T>n) {Stk2[++top2] = val; return;}
Dfs2(val,T+); Dfs2(val+a[T],T+);
} s64 Judge(int i,int j)
{
return Check(Stk1[j] + Stk2[i],tot - Stk1[j] -Stk2[i]);
} double Random() {return (double)rand()/RAND_MAX;}
void Deal(int id)
{
int Now = top2/;
double Temper = top2/;
while(Temper >= )
{
int A = Now + (int)Temper * (Random()*2.0-);
if(A<=) A = (int)Temper * Random() + ;
s64 dE = Judge(A,id) - Judge(Now,id);
if(dE > || Random()<=exp(dE))
Now = A;
if(Temper > top2 / ) Temper *= 0.1;
Temper *= 0.75;
}
Judge(Now-,id); Judge(Now+,id);
} void Solve2()
{
top1 = top2 = tot = ;
for(int i=;i<=n;i++) a[i]=get(),a[i]*=,tot += a[i];
Dfs1(,); sort(Stk1+,Stk1+top1+); top1 = unique(Stk1+,Stk1+top1+)-Stk1-;
Dfs2(,n/+); sort(Stk2+,Stk2+top2+); top2 = unique(Stk2+,Stk2+top2+)-Stk2-;
Ans = Square = ; for(int i=;i<=top1;i++)
Deal(i); printf("%lld\n",Ans/);
} void Dfs(s64 A,s64 B,int T)
{
if(T>n)
{
Check(A,B);
return;
}
Dfs(A+a[T],B,T+);
Dfs(A,B+a[T],T+);
} void Solve1()
{
Ans = Square = ;
for(int i=;i<=n;i++) a[i]=get(),a[i]*=;
Dfs(,,);
printf("%lld\n",Ans/);
} int main()
{
srand(time());
while(scanf("%d",&n)!=EOF)
{
if(n <= ) Solve1();
else Solve2();
}
}
【Foreign】咏叹 [模拟退火]的更多相关文章
- 【Foreign】Bumb [模拟退火]
Bumb Time Limit: 20 Sec Memory Limit: 512 MB Description Input Output Sample Input 4 1 5 1 4 Sample ...
- bzoj3680模拟退火
看题意就是一道数学物理题,带权费马点 --这怎么是数学了,这也是物理的 所以要用物理方法,比如FFF 国际著名oi选手miaom曾说 模拟退火初温可以低,但是最好烧个几千次 国际著名物理课代表+1 ...
- Constraint6:更新外键约束(Foreign Key Constraint)的引用列
在SQL Server中,表之间存在引用关系,引用关系通过创建外键约束(Foreign Key Constraint)实现.如果一个Table中的column被其他Table引用,那么该表是参考表,或 ...
- MySQL主从复制中断,报“Error on master: message (format)='Cannot delete or update a parent row: a foreign key constraint fails' error code=1217” 错误
前几天,发现从库挂了,具体报错信息如下: 分析思路 1. 因为我采用的是选择性复制,只针对以下几个库进行复制: card,upay,deal,monitor,collect.所以,不太可能出现对于sa ...
- ORA-02266: unique/primary keys in table referenced by enabled foreign keys
在数据库里面使用TRUNCATE命令截断一个表的数据时,遇到如下错误 SQL >TRUNCATE TABLE ESCMOWNER.SUBX_ITEM ORA-02266: unique/prim ...
- SQL Server 2008 R2——TRUNCATE TABLE 无法截断表 该表正由 FOREIGN KEY 约束引用
=================================版权声明================================= 版权声明:原创文章 禁止转载 请通过右侧公告中的“联系邮 ...
- 【MySQL】Create table 以及 foreign key 删表顺序考究。
1.以下是直接从数据库导出的建表语句. 1 -- ---------------------------- 2 -- Table structure for files 3 -- ---------- ...
- MYSQL外键(Foreign Key)的使用
在MySQL 3.23.44版本后,InnoDB引擎类型的表支持了外键约束.外键的使用条件:1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持): ...
- 无题的题 & 模拟退火...
题意: 给你不超过8条一端在圆心的半径,求他们组成的凸包的最大面积. SOL: 正解怎么搞啊不会啊...然后昨天毛爷爷刚讲过模拟退火...那么就打一个吧... 然后就T了,不过三角形的部分分妥妥的.. ...
随机推荐
- 2017-2018-2 20172314 『Java程序设计』课程 结对编程练习_四则运算
相关过程截图 截图为我负责的部分关于计算的测试 关键代码解释 根据代码中的部分解释,这部分代码实现了结果的整数和分数的输出,如果算出的结果为一个真分数,就输出真分数的形式,如果结果为整数,就输出整数形 ...
- Linux GCC编译
.a 静态库(打包文件 由多个.o文件打包而成) .c 未经过预处理的C源码 .h C头文件 .i 经过预处理的C源码(将头文件内容加载到c文件中) .o 编译之后产生的目标文件 .s 生成的汇编语言 ...
- c#调用c++dll(c++界面在c#显示)____制作dll
1.c++dll含界面,以摄像头dll为例: 1.直接在c++SDK上调试运行成功,生成dll. 2.留一个调用接口(格式如下,写在cpp文件中,即函数体): extern "C" ...
- android入门 — ListView点击事件
listView中提供了两种点击事件的处理方法,分别是OnItemClick和OnItemLongClick. OnItemClick提供的是点击操作的处理,OnItemLongClick提供的是长按 ...
- LintCode-378.将二叉查找树转换成双链表
将二叉查找树转换成双链表 将一个二叉查找树按照中序遍历转换成双向链表. 样例 给定一个二叉查找树: 返回 1<->2<->3<->4<->5. 标签 链 ...
- mysql学习之主从复制
该文使用mysql5.5 centos6.5 64位 一.主从复制的作用 1.如果主服务器出现问题,可以快速切换到从服务器. 2.对与实时性要求不高或者更新不频繁的应用可以在从服务器上执行查询操作,降 ...
- [剑指Offer] 56.删除链表中重复的结点
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- 7款很棒的 HTML5 视频播放器
做个连接:http://www.cnblogs.com/lhb25/archive/2011/06/27/7-great-html-5-video-player-scripts.html
- 前端开发学习之——dom ready和window onload的区别
1.ready事件是在页面中所有DOM结构已完全加载时执行,监听的是 DomContentload 事件,初始化并解析完成时触发,不需要等待样式表.图片和 iframes 加载完,也就是说当这个事件触 ...
- BZOJ3990:[SDOI2015]排序——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3990 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作 ...