POJ 1190 生日蛋糕 搜索dfs

http://poj.org/problem?id=1190

经典的搜索, 题目因为比较复杂就不形容了,这里说下剪枝的技巧:

剪枝1 :在第i层的时,若i+1 -- n 层取最小, 总体积大于N ,则剪枝 ;

剪枝2 :在第i层的时,若i+1 -- n 层取最小, 总表面积大于ans  ,则剪枝 ;

剪枝3 : 因为前i层的体积为sumv,那么剩余的m-i层的体积满足:n-sumv=(h[k]*(r[k]^2)+……+h[1]*(r[1]^2)) ,(k = i...1) ;而剩余部分的表面积满足:lefts=2*(r[k]*h[k]+……+r[1]*h[1])>2*(n-sumv)/r[i] ,(k = i...1)  ; 显然有上述不等式lefts=best-sums>2*(n-sumv)/r,即2*(n-sumv)/r+sums<best,所以当2*(n-sumv)/r[i]+sums>=best时也可以进行剪枝.  ----------------------神级剪枝, 没有想到

代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
int n ,m ;
int ans ;
int mins[21] ,minv[21] ;
const int INF = 0x7fffff ; 

void dfs( int k,int sums,int sumv,int r, int h ){
	if( k == 0 ){
		if( sumv == n && ans > sums )
			ans = sums ;
		return ;
	}
	if( minv[ k ] + sumv > n)	return ;
	if( mins[ k ] + sums >= ans )	return ;
	if( 2 * (n - sumv)/r + sums >= ans)	return ;
	int rr ,hh ;
	for( rr = r - 1 ; rr >= k ; rr--){
		if(k==m){
			sums = rr *rr ;
		}
		for(hh= h -1 ; hh>=k;hh--){
			dfs(k-1,sums+2*rr*hh,sumv+rr*rr*hh,rr,hh);
		}
	}
}

int main(){
		scanf("%d %d",&n,&m);
		mins[0] = minv[0] = 0 ;
		for(int i=1;i<=m;i++){
			mins[i] = mins[i-1] + 2 * i * i;
			minv[i] = minv[i-1] + i * i * i ;
		}
		ans = INF ;
		int r = (int)sqrt(n - minv[m-1]) + 2 ;
		int h = n - minv[m-1] + 1 ;
		dfs( m , 0 , 0 , r , h ) ;
		if(ans == INF)	
			ans = 0 ;
		printf("%d\n",ans);	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值