【每日一题】BOWL 碗的叠放

[ZJOI2006]BOWL 碗的叠放

https://ac.nowcoder.com/acm/problem/20464

BOWL 碗的叠放

解题思路:
n只有9的大小,因此我们可以枚举碗的拜访顺序。接下来就是判断碗要怎么叠加
我们可以考虑碗的斜边斜率的关系
1)如果两者相等,要么可以放进去要不就不能放进去,
2)如果要放的小于已经放的,同样要放的底边可以放到已放的底边或者不能放到已放的底边,同样是两种情况
3)大于,同样是两种情况就不做图了,自己应该可以画出来

接着就是根据以上可以放的情况来算下底面的高度,找到最小值即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct no
{
	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;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>bowl[i].h>>bowl[i].r1>>bowl[i].r2;
		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;
	
 } 


全部评论

相关推荐

牛客963010790号:为什么还要收藏
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务