woc, 13年前的ZJOI就这么毒瘤的嘛。。。

题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=1859

(luogu)https://www.luogu.org/problemnew/show/P2589

题解: 大分类讨论,预处理\(ints[i][j]\)表示碗\(i\)叠在\(j\)上,\(i\)的底部比\(j\)的底部要高多少

然后分类讨论求此数组:

(1) \(i\)的下半径比\(j\)的上半径大,则等于\(j\)的高度

(2) \(i\)的上半径比\(j\)的下半径小,则等于零

(3) \(i\)的碗壁斜率大于\(j\)的碗壁斜率

(3.1) 若\(i\)的下半径小于等于\(j\)的下半径,则为零

(3.2) 若\(i\)的下半径大于\(j\)的下半径,则接触点横坐标为\(i\)的下半径,通过\(j\)的一次函数计算高度即可

(4) \(i\)的碗壁斜率小于\(j\)的碗壁斜率

(4.1) 若\(i\)的上半径大于等于\(j\)的上半径,则接触点为\(j\)的口处,通过\(i\)的一次函数计算高度

(4.2) 若\(i\)的上半径小于\(j\)的上半径,则(不妨先不考虑碗底)接触点横坐标为\(i\)的上半径,通过\(j\)的一次函数计算高度

情况(4)最后求出来的高度和\(0\)取Max.

(5) 若\(i\)和\(j\)碗壁斜率相等

(5.1) 若\(i\)的下半径小于等于\(j\)的下半径,则高度为\(0\).

(5.2) 若\(i\)的下半径大于\(j\)的上半径,则接触点横坐标为\(i\)的下半径,通过一次函数计算高度即可。

然后一个显然的性质是一个碗叠在一摞碗上,它的叠放高度为和每个碗分别叠放的高度的Max.

时间复杂度\(O(n!\times n)\)

这题……我还能说什么呢23333

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<algorithm>
using namespace std; const int N = 9;
struct Element
{
int h,r1,r2;
double calc(double x) {return h*(x-(double)r1)/((double)r2-r1);}
} a[N+3];
double hh[N+3];
int permu[N+3];
double ints[N+3][N+3];
int n; double intersect(int x,int y)
{
// printf("Intersect (%d,%d)\n",x,y);
double ret;
if(a[x].r1>a[y].r2) {ret = a[y].h;/* printf("Case 1\n");*/}
else if(a[x].r2<a[y].r1) {ret = 0;/* printf("Case 2\n");*/}
else if((a[y].r2-a[y].r1)*a[x].h>(a[x].r2-a[x].r1)*a[y].h)
{
if(a[x].r1<=a[y].r1) {ret = 0;/* printf("Case 3.1\n");*/}
else {ret = a[y].calc((double)a[x].r1);/* printf("Case 3.2\n");*/}
}
else if((a[y].r2-a[y].r1)*a[x].h<(a[x].r2-a[x].r1)*a[y].h)
{
if(a[x].r2>=a[y].r2) {ret = a[y].h-a[x].calc(a[y].r2);/* printf("Case 4.1\n");*/}
// else if(a[x].h*(a[y].r2-a[y].r1)<=a[y].h*(a[x].r2-a[y].r1)) {ret = 0;}
else {ret = a[y].calc(a[x].r2)-a[x].calc(a[x].r2);/* printf("Case 4.2\n");*/}
if(ret<0) ret = 0;
}
else
{
if(a[x].r1<=a[y].r1) {ret = 0;/* printf("Case 5.1\n");*/}
else {ret = a[y].calc(a[x].r1);/* printf("Case 5.2\n");*/}
}
// printf("ret=%lf\n",ret);
return ret;
} double calc()
{
// printf("calc: "); for(int i=1; i<=n; i++) printf("%d ",permu[i]); puts("");
double ret = 0.0;
for(int i=1; i<=n; i++)
{
hh[i] = 0;
for(int j=1; j<i; j++)
{
hh[i] = max(hh[i],hh[j]+ints[permu[i]][permu[j]]);
}
ret = max(ret,hh[i]+a[permu[i]].h);
}
// printf("Total=%lf\n",ret); puts("");
return ret;
} int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d%d%d",&a[i].h,&a[i].r1,&a[i].r2);
for(int i=1; i<=n; i++) permu[i] = i;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(i==j) continue;
ints[i][j] = intersect(i,j);
}
}
double ans = 1e6;
do
{
ans = min(ans,calc());
} while(next_permutation(permu+1,permu+n+1)); printf("%d\n",(int)(ans+0.5));
return 0;
}

BZOJ 1859 Luogu P2589 [ZJOI2006]碗的叠放 (计算几何)的更多相关文章

  1. [ZJOI2006]碗的叠放

    Description 小H有n个碗需要放进橱柜,她希望将他们叠起来放置.你知道每个碗都是规则的圆柱体,并且都是上宽下窄,你已经测量出了每个碗的两个半径及高,请你帮小H找出一种叠放顺序,使得叠放出来的 ...

  2. 【BZOJ1859】【ZJOI2006】碗的叠放

    题目大意:给你n个碗,求如何堆叠,使得它们的总高度最低. 首先,我们枚举碗的叠放顺序. 假设我们已经堆好了前i个碗,那么在堆第i+1个碗时,我们要将第i+1个碗与前i个碗比较,确定第i+1个碗的离地高 ...

  3. [Luogu 2596] ZJOI2006 书架

    [Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...

  4. BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)

    题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ...

  5. BZOJ 3931 / Luogu P3171 [CQOI2015]网络吞吐量 (最大流板题)

    题面 中文题目,不解释: BZOJ传送门 Luogu传送门 分析 这题建图是显然的,拆点后iii和i′i'i′连容量为吞吐量的边,根据题目要求,111和nnn的吞吐量看作∞\infty∞. 然后用di ...

  6. BZOJ 3894 / Luogu P4313 文理分科 (拆点最小割)

    题面 中文题面- BZOJ 传送门 Luogu 传送门 分析 这道题类似于BZOJ 3774 最优选择,然后这里有一篇博客写的很好- Today_Blue_Rainbow's Blog 应该看懂了吧- ...

  7. BZOJ 2039 / Luogu P1791 [2009国家集训队]employ人员雇佣 (最小割)

    题面 BZOJ传送门 Luogu传送门 分析 考虑如何最小割建图,因为这仍然是二元关系,我们可以通过解方程来确定怎么建图,具体参考论文 <<浅析一类最小割问题 湖南师大附中 彭天翼> ...

  8. BZOJ 2127 / Luogu P1646 [国家集训队]happiness (最小割)

    题面 BZOJ传送门 Luogu传送门 分析 这道题又出现了二元关系,于是我们只需要解方程确定怎么连边就行了 假设跟SSS分在一块是选文科,跟TTT分在一块是选理科,先加上所有的收益,再来考虑如何让需 ...

  9. [BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表)

    [BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表) 题面 Byteasar 想在墙上涂一段很长的字符,他为了做这件事从字符的前面一段中截取了一段 ...

随机推荐

  1. [Python3] 026 常用模块 calendar

    目录 calendar 1. calendar.calendar(year, w, l, c, m) 2. calendar.prcal(year, w, l, c, m) 3. calendar.m ...

  2. Linux下面MariaDB 管理命令基础使用

    MariaDB 是 MySQL 的一个分,由于某些原因,使之取代了Mysql成为了 RHEL/CentOS 7 的默认数据库.针对数据库的操作我们经常做的操作就是增删查改,接下来就介绍下 MariaD ...

  3. [转帖]虚拟内存探究 -- 第四篇:malloc, heap & the program break

    虚拟内存探究 -- 第四篇:malloc, heap & the program break http://blog.coderhuo.tech/2017/10/19/Virtual_Memo ...

  4. 洛谷 P1578 奶牛浴场 题解

    题面 1.定义有效子矩形为内部不包含任何障碍点且边界与坐标轴平行的子矩形.如图所示,第一个是有效子矩形(尽管边界上有障碍点),第二个不是有效子矩形(因为内部含有障碍点). 2.极大有效子矩形:一个有效 ...

  5. 三校联训 【NOIP模拟】寻找

    题面 “我有个愿望,我希望穿越一切找到你.” 这是个二维平面世界,平面上有n个特殊的果实,我从(0,0)点出发,希望得到尽量多的果实,但是出于某种特殊的原因,我的运动方式只有三种(假设当前我在(x,y ...

  6. P1057传球游戏

    这是一道动态规划的水题,难度为提高-. 题意为:n个人围成一个环传球,每一次都可以往左或右传,传m次,问有几种最后传到小明手里的方案数.然后因为一个状态有两个变量,所以我们用dp[][]来存储[传球次 ...

  7. cmd内部命令和外部命令的区别

    内部命令 我们可以直接在CMD下就可以执行的命令,例如:telnet.ftp.dir.cd.等等,你可以在CMD下输入help进行查看 外部命令 就是cmd下不能直接运行的命令,(例如大家常用的nc) ...

  8. 23、selenium爬取歌曲精彩评论

    我们这次试试用selenium爬取QQ音乐的歌曲评论,我选的歌是<甜甜的>.   https://y.qq.com/n/yqq/song/000xdZuV2LcQ19.html     f ...

  9. JS作用域及域解析规则

    1.JS作用域:变量和函数作用的范围. 2.JS解析器可以分为域解析和逐行解读代码两个过程. 域解析:1.当进行域解析的时候,一旦找到var,就会提取后面的变量名,并给它赋值给undefined. 2 ...

  10. 在easyui中解决使west和center为1:1,并且拖动窗口时能够自适应变化

    <script type="text/javascript"> // 解决页面两个grid的布局问题 $(function(){// 在页面加载完毕后 //consol ...