码迷,mamicode.com
首页 > 其他好文 > 详细

[NOI1999]生日蛋糕

时间:2017-11-14 17:18:11      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:std   生日   高度   return   ==   str   剪枝   ++   半径   

题目:洛谷P1731、Vijos P1297、codevs1710。

题目大意:让你做一个体积为$N\pi$的每层都是圆柱的蛋糕,m层,且从下到上每层的高度和半径都不超过下面一层的,且是整数。

设表面积Q=$S\pi$,问你最小的S是多少(不可能输出0)。

解题思路:搜索即可。

首先发现此题与$\pi$没什么关系,可以直接消去,我们忽略即可。

以下所讲的表面积体积均忽略$\pi$。

注意以下三种剪枝:

①当前表面积加上上面几层的最小表面积大于当前答案则退出。

②当前体积加上上面几层的最小体积大于N则退出。

③当前剩余体积全部做成与上一层半径相同的蛋糕,表面积大于当前答案则退出。

然后倒着枚举半径和高即可(倒着搜总会快那么一丁点)。

然后就完美地AC了。

C++ Code:

#include<cstdio>
#include<cmath>
int n,m,mv[16],ms[16],ans=0x3fffffff;
void dfs(int now,int s,int v,int preh,int prer){
	if(!now){
		if(v==n&&ans>s)ans=s;
		return;
	}
	if(s+ms[now]>ans||v+mv[now]>n||s+2*(n-v)/prer>ans)return;
	for(int r=prer-1;r>=now;--r){
		if(now==m)s=r*r;
		for(int h=preh-1;h>=now;--h)
		dfs(now-1,s+2*r*h,v+r*r*h,h,r);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	ms[0]=ms[0]=0;
	for(int i=1;i<=m;++i)
	mv[i]=mv[i-1]+i*i*i,ms[i]=ms[i-1]+((i*i)<<1);
	dfs(m,0,0,n,(int)(sqrt(n)+1e-9));
	printf("%d\n",(ans==0x3fffffff)?0:ans);
	return 0;
}

 

[NOI1999]生日蛋糕

标签:std   生日   高度   return   ==   str   剪枝   ++   半径   

原文地址:http://www.cnblogs.com/Mrsrz/p/7833336.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!