欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java数据结构算法(制作N层蛋糕)

程序员文章站 2022-03-22 10:20:54
题目出处说明:以下文字中把最上层当作第1层,最下层当作第M层,和代码一致思路:首先明确要对什么东西搜索,很明显题目告诉我们了,要对R和H搜,顺便记一下每一次的层数、体积、面积 只要层数到达最后一层记录面积就完事了比较容易想到的剪枝:1、面积大于min,return 2、体积大于n,return但是仅仅这么两个简单的剪枝只有30分。后来经过观察发现最上面一层最小体积为111,第二层及以上最小体积为222+111。因此我们有了新的剪枝:①已有体积+此层及以上最小体积大于n,returnj既然体积...

题目出处
Java数据结构算法(制作N层蛋糕)

说明:以下文字中把最上层当作第1层,最下层当作第M层,和代码一致

思路:首先明确要对什么东西搜索,很明显题目告诉我们了,要对R和H搜,顺便记一下每一次的层数、体积、面积 只要层数到达最后一层记录面积就完事了
比较容易想到的剪枝:1、面积大于min,return 2、体积大于n,return
但是仅仅这么两个简单的剪枝只有30分。后来经过观察发现最上面一层最小体积为1*1*1,
第二层及以上最小体积为2*2*2+1*1*1。
因此我们有了新的剪枝:①已有体积+此层及以上最小体积大于n,return
既然体积可以剪枝,那我们面积肯定也行啊!所以又发现面积剪枝:2*(n-已有体积)/上一层的半径r代表在现有体积的条件下,余下层数最小的侧面积和。在这里,因为r是上一层的半径,但是这一层的半径肯定是小于r的,因此这样算出的侧面积肯定是在现有体积的前提下余下层数最小的侧面积和。
因此我们又有了新的剪枝:②已有面积+2(n-已有体积)/上一层的半径r大于min,return
是否有了这两个剪枝就可以AC了呢,显然不是,我们发现需要对R、H的上下限进行处理,比如R的上限是根号N,H上限就是N,H和R的下限都是其所在层数,上限代码里有解释,这里解释下限:比如最上面一层R最小为1,H最小为1,又因为往下R,H逐层递增且都为正整数,所以第二层R,H最小为2,以此类推,第i层R,H最小值为i。

解释就到这里了,还要提醒一点:函数里不要有太多参数!!!否则极大可能会TLE
(因为第一次我传了7个参数,结果30分都没有,只有10分~~~

代码很详细:

package search; import java.util.Scanner; public class P1731 { static int N, M, min = Integer.MAX_VALUE, a[]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); N = sc.nextInt(); M = sc.nextInt(); //我们规定最上层为第1层,则最下层为第m层 a = new int[M + 1];// 存储第i层即上面所有层的体积最小值 a[0] = 0; for (int i = 1; i <= M; i++) { a[i] = a[i - 1] + i * i * i;// V=pi*r*r*h,这里略去了pi,r和h每层最小值为i } //		dfs(N+1, N+1, M, 0, 0); //在这里我们从最下层开始搜,也就是第m层 dfs((int)Math.sqrt(N)+1, N+1, M, 0, 0);//pi*r*r*h<=pi*N,h最小值为1,所以r取N开方,+1是为了和dfs函数匹配 System.out.println(min); } // dfs /**
	 * 
	 * @param h 高度
	 * @param r 半径
	 * @param c 层数
	 * @param v 目前的体积和
	 * @param s 目前的面积和
	 */ public static void dfs(int r, int h, int c, int v, int s) {//s就是最下层上表面面积+所有层的侧面积 if (c == 0) {// 蛋糕已完成 if (v == N) { min = Math.min(min, s); } return; } if (v + a[c] > N) {// 如果当前体积+所在层最小体积大于N return; } if (s + 2 * (N - v) / r >= min) {//r为上一层的半径,如果当前体积s+之后最小表面积大于等于min return; } for (int i = r-1; i >= c; --i) {//搜半径,上限为下层半径-1,下限为层数 if (c == M) {//第一层的s加上其上表面面积 s = i*i; } for (int j = h-1; j >= c; --j) {//搜高度,,上限为下层高度-1,下限为层数 dfs(i,j, c-1, v+i*i*j, s+2*i*j); } } } } 

本文地址:https://blog.csdn.net/TXXERIN/article/details/107891998

相关标签: 算法