题意:
有
n
个
倒
梯
形
,
上
宽
下
窄
的
碗
有n个倒梯形,上宽下窄的碗
有n个倒梯形,上宽下窄的碗
他
们
的
下
底
边
是
r
1
,
上
底
边
是
r
2
,
高
是
h
他们的下底边是r1,上底边是r2,高是h
他们的下底边是r1,上底边是r2,高是h
求
出
碗
叠
放
的
最
低
高
度
求出碗叠放的最低高度
求出碗叠放的最低高度
题解:
n
<
=
10
n<=10
n<=10
所
以
直
接
枚
举
放
碗
顺
序
,
找
一
下
怎
么
能
最
低
所以直接枚举放碗顺序,找一下怎么能最低
所以直接枚举放碗顺序,找一下怎么能最低
然
后
考
虑
放
碗
的
高
度
然后考虑放碗的高度
然后考虑放碗的高度
可
以
考
虑
的
是
,
把
x
碗
放
到
y
碗
上
,
x
碗
的
下
底
的
高
度
可以考虑的是,把x碗放到y碗上,x碗的下底的高度
可以考虑的是,把x碗放到y碗上,x碗的下底的高度
第
一
种
情
况
第一种情况
第一种情况
很
明
显
,
x
的
下
底
大
于
y
的
上
底
很明显,x的下底大于y的上底
很明显,x的下底大于y的上底
所
以
x
的
下
底
高
度
直
接
是
h
y
所以x的下底高度直接是h_y
所以x的下底高度直接是hy
第
二
种
情
况
第二种情况
第二种情况
x
的
上
底
小
于
y
的
下
底
,
肯
定
是
直
接
能
放
进
y
里
的
x的上底小于y的下底,肯定是直接能放进y里的
x的上底小于y的下底,肯定是直接能放进y里的
所
以
这
个
时
候
x
的
下
底
高
度
就
是
0
所以这个时候x的下底高度就是0
所以这个时候x的下底高度就是0
第
三
种
情
况
是
x
的
边
斜
率
大
于
等
于
y
第三种情况是x的边斜率大于等于y
第三种情况是x的边斜率大于等于y
这
里
又
分
出
来
两
种
情
况
这里又分出来两种情况
这里又分出来两种情况
根
据
图
片
也
很
容
易
看
出
根据图片也很容易看出
根据图片也很容易看出
分
别
是
x
的
下
底
大
于
和
小
于
y
的
下
底
的
情
况
分别是x的下底大于和小于y的下底的情况
分别是x的下底大于和小于y的下底的情况
小
于
的
时
候
很
明
显
,
是
0
小于的时候很明显,是0
小于的时候很明显,是0
大
于
的
时
候
就
要
考
虑
一
下
了
大于的时候就要考虑一下了
大于的时候就要考虑一下了
假
设
x
的
下
底
高
度
为
h
假设x的下底高度为h
假设x的下底高度为h
那
么
可
以
找
到
一
个
比
例
式
r
2
y
−
r
1
y
h
y
=
r
1
x
−
r
1
y
h
那么可以找到一个比例式\frac{r2_y-r1_y}{h_y}=\frac{r1_x-r1_y}{h}
那么可以找到一个比例式hyr2y−r1y=hr1x−r1y
其
实
就
是
两
个
斜
率
相
等
列
出
的
式
子
,
这
样
就
可
以
算
出
h
了
其实就是两个斜率相等列出的式子,这样就可以算出h了
其实就是两个斜率相等列出的式子,这样就可以算出h了
第
四
种
情
况
,
就
是
x
的
斜
率
小
于
y
第四种情况,就是x的斜率小于y
第四种情况,就是x的斜率小于y
这
里
也
有
两
种
情
况
这里也有两种情况
这里也有两种情况
分
别
是
x
的
上
底
大
于
和
小
于
y
的
上
底
分别是x的上底大于和小于y的上底
分别是x的上底大于和小于y的上底
大
于
的
情
况
就
是
用
h
y
减
去
y
的
上
底
到
x
的
下
底
的
距
离
大于的情况就是用h_y减去y的上底到x的下底的距离
大于的情况就是用hy减去y的上底到x的下底的距离
用
类
似
刚
才
的
斜
率
公
式
就
可
以
算
出
来
用类似刚才的斜率公式就可以算出来
用类似刚才的斜率公式就可以算出来
最
终
下
底
高
度
为
h
y
−
h
x
∗
r
2
y
−
r
1
x
r
2
x
−
r
1
x
最终下底高度为h_y-h_x*\frac{r2_y-r1_x}{r2_x-r1_x}
最终下底高度为hy−hx∗r2x−r1xr2y−r1x
小
于
的
情
况
就
是
用
x
的
上
底
到
y
的
下
底
的
距
离
减
去
h
x
小于的情况就是用x的上底到y的下底的距离减去h_x
小于的情况就是用x的上底到y的下底的距离减去hx
最
终
为
h
y
∗
r
2
x
−
r
1
y
r
2
y
−
r
1
y
−
h
x
最终为h_y*\frac{r2_x-r1_y}{r2_y-r1_y}-h_x
最终为hy∗r2y−r1yr2x−r1y−hx
到
这
就
把
两
两
组
合
全
部
的
下
底
高
度
算
出
来
了
到这就把两两组合全部的下底高度算出来了
到这就把两两组合全部的下底高度算出来了
然
后
对
于
每
种
排
列
,
一
个
一
个
放
,
放
的
时
候
找
当
前
放
的
碗
然后对于每种排列,一个一个放,放的时候找当前放的碗
然后对于每种排列,一个一个放,放的时候找当前放的碗
和
前
面
每
个
组
合
一
下
看
看
最
高
是
哪
一
个
,
这
就
是
当
前
的
高
度
和前面每个组合一下看看最高是哪一个,这就是当前的高度
和前面每个组合一下看看最高是哪一个,这就是当前的高度
由
于
算
出
的
是
下
底
高
度
,
最
后
结
果
要
加
上
当
前
碗
的
高
度
由于算出的是下底高度,最后结果要加上当前碗的高度
由于算出的是下底高度,最后结果要加上当前碗的高度
AC代码
/*
Author : zzugzx
Lang : C++
Blog : blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define endl '\n'
#define SZ(x) (int)x.size()
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int mod = 1e9 + 7;
//const int mod = 998244353;
const double eps = 1e-10;
const double pi = acos(-1.0);
const int maxn = 1e6 + 10;
//const int N = 1e3 + 10;
const ll inf = 0x3f3f3f3f;
const int dir[][2]={{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
double h[maxn], r1[maxn], r2[maxn], tmp[maxn];
double calc(int x, int y) {
if (r1[x] > r2[y])
return h[y];
if (r2[x] < r1[y])
return 0;
if ((r2[x] - r1[x]) * h[y] <= (r2[y] - r1[y]) * h[x]) {
if (r1[x] <= r1[y]) return 0;
return h[y] * (r1[x] - r1[y]) / (r2[y] - r1[y]);
}
if (r2[x] > r2[y])
return max(0.0, h[y] - h[x] * (r2[y] - r1[x]) / (r2[x] - r1[x]));
return max(0.0, h[y] * (r2[x] - r1[y]) / (r2[y] - r1[y]) - h[x]);
}
int id[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> h[i] >> r1[i] >> r2[i], id[i] = i;
double ans = inf, res = 0;
do{
res = 0;
for (int i = 1; i <= n; i++){
tmp[i] = 0;
for (int j = 1; j < i; j++)
tmp[i] = max(tmp[i], tmp[j] + calc(id[i], id[j]));
res = max(tmp[i] + h[id[i]], res);
}
ans = min(ans, res);
}while(next_permutation(id + 1, id + 1 + n));
cout << (int)(ans + 0.5);
return 0;
}