题目描述
小H有n个碗需要放进橱柜,她希望将他们叠起来放置。你知道每个碗都是规则的圆柱体,并且都是上宽下窄,你已经测量出了每个碗的两个半径及高,请你帮小H找出一种叠放顺序,使得叠放出来的碗堆的高度尽量小,比如:
100%数据满足n < = 9。所有输入的数绝对值不超过1000。
输入描述:
第一行一个整数n,表示碗的数目。
以下n行,每行三个整数h,r1,r2。分别表示碗高及两个半径。其中r1<r2
输出描述:
仅一个数,表示最小的高度。答案四舍五入取整。
题意
给定 n 个碗,然后给出宽和高,问所有的碗叠放在一起,的最小高度多少?
思路
因为n很小,所以这里可以尝试直接暴力枚举,直接枚举所有的排列组合,计算高度即可。
因为画图水平有限,我这里图就直接偷了,原图博客在这里
要注意第二种情况,小碗在大碗里面,所以相当于底部升高了一部分
按照上面图的几种情况,分类判断计算就好(几何太麻烦了
代码
#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline void write(__int128 x) { if (!x) { putchar('0'); return; } char F[50]; __int128 tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); }
#define pb push_back
#define pll pair<ll,ll>
#define INF 0x3f3f3f3f
const int mod = 1e9+7;
const int maxn = 55;
#define stop system("pause")
#define PI acos(-1.0)
inline ll read(){
ll s = 0, w = 1; char ch = getchar();
while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
return s * w;
}
struct node{
double h,r1,r2;
}bowl[10];
int id[15];
double temp[15];
double cal(int x,int y){
if(bowl[x].r1>bowl[y].r2) return bowl[y].h;
if(bowl[x].r2<bowl[y].r1) return 0;
if((bowl[x].r2-bowl[x].r1)*bowl[y].h<=(bowl[y].r2-bowl[y].r1)*bowl[x].h){
if(bowl[x].r1<=bowl[y].r1) return 0;
return bowl[y].h*(bowl[x].r1-bowl[y].r1)/(bowl[y].r2-bowl[y].r1);
}
if(bowl[x].r2>bowl[y].r2){
return max(0.0,bowl[y].h-bowl[x].h*(bowl[y].r2-bowl[x].r1)/(bowl[x].r2-bowl[x].r1));
}
return max(0.0,bowl[y].h*(bowl[x].r2-bowl[y].r1)/(bowl[y].r2-bowl[y].r1)-bowl[x].h);
}
int main(){
int n = read();
for(int i=1;i<=n;i++){
bowl[i].h = read();bowl[i].r1 = read();
bowl[i].r2 = read();id[i]=i;
}
double ans = 0x3f3f,res=0;
do{
res=0;
for(int i=1;i<=n;i++){
temp[i]=0;
for(int j=1;j<i;j++){
temp[i]=max(temp[i],temp[j]+cal(id[i],id[j]));
}
res=max(temp[i]+bowl[id[i]].h,res);
}
ans=min(ans,res);
}while(next_permutation(id+1,id+1+n));
cout<<(int)(ans+0.5)<<endl;
}
京公网安备 11010502036488号