poj 1190 dfs+剪枝

本文介绍了一种解决蛋糕堆叠问题的算法实现,通过深度优先搜索策略来寻找构成特定体积所需的最小表面积组合,利用多种剪枝策略提高搜索效率。

点击打开链接http://poj.org/problem?id=1190

#include <iostream>
#include <algorithm>
#include <cmath>
#define M1 30
using namespace std; //Q=Sπ求最小S->外表面最小  = (侧面积面积+底面积(中间部分都投影到底面))最小  
int MinA[M1]; 	//i层 cake的最小表面积  
int MinV[M1];
int ans=1<<30,area=0,n,M;
int MaxV(int MaxR,int MaxH,int m)
{
	int v=0;
	for(int i=0;i<m;i++)
	{
		v+=(MaxR-i)*(MaxR-i)*(MaxH-i); //体积最大 每层r和h都最大  
	}
	return v;
}
void dfs(int n,int m,int MaxR,int MaxH)
{
	if(m==0) 
	{
		if(n) //m层都搭完了 体积还没完 
		{
			return;
		}
		else
		{
			ans=min(ans,area);
		}
	}
	if(n<0) return;
	
	if(MaxR<m||MaxH<m) //可行性cut: 从下往上 r和h递减 (不能为负) 
	return;
	if(MinV[m]>n) //可行性cut:在搭m层最小体积都大于n 
	return;
	if(MaxV(MaxR,MaxH,m)<n)	//可行性cut:在搭m层最大体积都到不了n 
	return;
	if(area+MinA[m]>=ans) //最优性cut
	return;
	  
	int r,h;
	for(r=MaxR;r>=m;r--) //选择性少的先搜 
	{
		if(m==M) //底面积 
		{
			area=r*r; 
		}
		for(h=MaxH;h>=m;h--)
		{
			area+=2*r*h;
			dfs(n-r*r*h,m-1,r-1,h-1);
			area-=2*r*h;
		}
	}
	
}

int main()
{
	int i;// m层cake的体积n
	cin>>n>>M;
	MinA[0]=0;
	MinV[0]=0;
	for(i=1;i<=M;i++)
	{
		MinA[i]=MinA[i-1]+2*i*i;
		MinV[i]=MinV[i-1]+i*i*i;
	}
	if(MinV[M]>n) // 
	{
		cout<<0<<endl; 
		return 0;
	}
	int MaxH=(n-MinV[M-1])/(M*M)+1;// 最底层的最大高度 
	int MaxR=sqrt(double(n-MinV[M-1])/M)+1;
	dfs(n,M,MaxR,MaxH);//还差体积n 还差m层 
	if(ans==1<<30)
	{
		cout<<0<<endl;	
	} 
	else
	{
		cout<<ans<<endl;
	}
	return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值