ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

009

2022-03-19 09:33:04  阅读:171  来源: 互联网

标签:一层 剪枝 表面积 return int 体积 009


题目:https://www.luogu.com.cn/problem/P1731

题目简述:

做一个类似于动漫中的多层蛋糕

在限定体积和层数内寻找可能表面积中的最小值

思路:还是那失了双亲的深搜与剪枝

深搜基本思路:准备一个r[ ]和一个h[ ]分别存储第p层的半径和高

由底层开始,一步一步向上搜索

在体积不超限制的情况下,运用平移可得

整个蛋糕的表面积为每一层的侧面积和最底层的底面积

在比对即可

接下来,就可以开始考虑“剪枝”了

首先是上下界的问题

由于每一层都要比它的下面那层小

因此它的一个界就是它下面一层,也就是上一次我们搜索的那层半径(高)

注意,这一层永远比上一次我们搜索的那层小,记得-1

(我是用的i,j双层循环,一个半径一个高)

而另一个界,就来源于这句话:

要求R[i]>R[i+1]且H[i]>H[i+1]

所以我们需要给这一层上面每一层留一点

所以它的另一个界就是剩余层数(给每一层留个1意思意思得了)

但是在第一次的搜索中需要人为规定上界,否则会炸

其他的剪枝都在代码里,请君自便

#include<bits/stdc++.h>
using namespace std;
int n,m,h[16],r[16],minn=2147483647;
inline void dfs(int v,int k,int p,int s){
	//v为剩余体积,k为剩余层数
	//p为数组标记,s为当前表面积 
	if(v<0){//剩余体积不够
	//证明本蛋糕体积已经超出限制 
		return;//再见 
	}
	if(p>m+1){//数组超限
	//代表本蛋糕已经不符合层数要求 
		return;//再见 
	}
	if(s>=minn){//当前表面积超过测出的最小值
	//代表本蛋糕并非最优解 
		return;//再见 
	}
	if(s+k+r[1]*r[1]>minn){
	//当前表面积加上上底面积
	//再加上每层假定的最小表面积
	//(即直接认为以后每层表面积都是1)
	//还不是最优解 
		return;//再见 
	}
	if(v>r[p-1]*r[p-1]*h[p-1]*k){
	//当前体积如果大于
	//假定的最大体积
	//(即直接认为以后每层体积都是上一层的体积)
	//还是不够要求 
		return;//再见 
	}
	//上述就是剪枝1 
	if(v==0&&p==m+1){
	//如果恰好达到要求 
		s+=r[1]*r[1];//拼上上底面积 
		if(s<minn){//比曾经的最小值小 
			minn=s;//替换 
		}
		return;//再见 
	}
	int i,j;
	for(i=r[p-1]-1;i>=k;i--){
	//开始搜索(具体思路在上文,这里不过多赘述 
		for(j=h[p-1]-1;j>=k;j--){
			if(v>=i*i*j&&p<=m+1){
			//当前假定的这层蛋糕没有超过体积上限
			//并且层数没有超限 
				r[p]=i;//r[]存储第p层的半径 
				h[p]=j;//h[]存储第p层的高 
				dfs(v-i*i*j,k-1,p+1,s+i*2*j);//搜起来 
				r[p]=0;//回溯 
				h[p]=0;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	h[0]=(int)sqrt(n);//极大半径 
	r[0]=(int)sqrt(n);//极大高 
    //上面两行就是思路中说的“人为规定上界”
	dfs(n,m,1,0);
	if(minn==2147483647){//没变,即无解 
		printf("0");//再见 
	} 
	else{//有解 
		printf("%d",minn);//输出 
	}
	return 0;
}

总结:没什么可说的,该说的都在代码里

 

标签:一层,剪枝,表面积,return,int,体积,009
来源: https://www.cnblogs.com/a-001/p/16025466.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有