poj 生日蛋糕 搜索+剪枝
来源:互联网 发布:python爬虫怎么入门 编辑:程序博客网 时间:2024/05/16 09:41
Description
设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri > Ri+1且Hi > Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q = Sπ
请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。
(除Q外,以上所有数据皆为正整数)
Input
Output
Sample Input
1002
Sample Output
68
Hint
体积V = πR2H
侧面积A' = 2πRH
底面积A = πR2
题意:制作一个体积为N(这里的π全部可以省略, 因为都有π,最后相当于两边都消去)的M层蛋糕。蛋糕的特点是上边的层数至少比它下面一层的半径和高度至少都少一。求最少的侧面积s(蛋糕的外表面和上层 。ps:因为上层比下层小所以外表面也包括没有被上面一层蛋糕遮住的部分,这部分投影加上表面就是下表面,所以最后的表面积就是各层蛋糕的侧面加下表面的和)
解题思路:要求出最少的表面积的和,肯定是一直枚举半径和高度,然后算出最小的表面积,这样的话肯定是深搜,这个很容易想到。但是题意中体积最大是10000, 要枚举的话肯定会用时会特别多。应该加上一点剪枝。这个题必须用好几种剪枝才能过。
剪枝一:如果在搜索的过程中体积小于0 或者当前半径或高度小于剩余要制作的层数(因为每层必须是相差1的,当前半径或高度小于要制作的层数,肯定不能制作完)就要剪枝.
剪枝二:当前剩下m层需要制作,可以预测制作这m层蛋糕最少需要多少体积,如果这个最少的体积还大于当前剩余的体积,那个这个不必继续搜索,所以要剪枝。
剪枝三:因为要求求最小表面积,如果当前枚举到的面积已经大于要求得的最优表面积,就要剪枝,但是这个剪枝还可以更优化,根据剪枝二的启发,如果当前枚举到的面积加上制作剩余m层蛋糕所要花费的最小表面积大于已经求得的最优解,那么剪枝。
剪枝四:因为体积必须为N,根据剪枝二,如果剩下m层蛋糕制作都按照最大的来,依然不能够使用完剩余的体积那么也要减掉。
根据上面四个剪枝,基本就能过这个题目.
代码:
#include<stdio.h>#include<string.h>#include<iostream>#include<math.h>#include<algorithm>#include<map>#include<queue>#include<set>using namespace std;int minA[30],minV[30], minArea, Area;int N, M;int maxvFormrh(int m, int r, int h){ int maxv = 0; for(int i = 0; i < m; i++) maxv += (r-i) * (r-i) *(h-i); return maxv;}void dfs(int n, int m, int r, int h){ if(m == 0) { if(n) return ; else if(minArea > Area) { minArea = Area; return ; } } if(n <= 0) // 剪枝1 return ; if(h < m || r < m)//剪枝1 return ; if(minV[m] > n)//剪枝2 return ; if(minA[m]+Area >= minArea) // 剪枝3 return; if(maxvFormrh(m,r,h) < n)//剪枝4 return ; for(int i = r; i >= m; i--) { if(m == M)//最下面一层 Area = i * i; for(int j = h; j >= m; j--) { Area += 2 * i * j; dfs(n - i*i*j, m-1, i-1, j-1); Area -= 2 * i * j; } }}int main(){ while(scanf("%d%d",&N,&M) != EOF) { minA[0] = 0; minV[0] = 0; for(int 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) { printf("0\n"); } else { int maxH = (N - minV[M-1]) / (M * M) + 1;//最大的高度 int maxR = sqrt((N - minV[M-1]) / M) + 1;//最大的体积 //Ps:上面的加1是因为避免出现小数取整,反正最后会减掉不必纠结。 minArea = 1 << 30; Area = 0; dfs(N, M, maxR, maxH); printf("%d\n",minArea); } } return 0;}
- poj 生日蛋糕 搜索+剪枝
- POJ 1190 生日蛋糕 搜索加剪枝
- poj1190 生日蛋糕 搜索+剪枝
- poj1190 生日蛋糕 (搜索剪枝)
- poj 1190 生日蛋糕 dfs 剪枝
- poj 1190 生日蛋糕 dfs剪枝
- Poj 1190 生日蛋糕 (DFS 剪枝)
- poj 1190 生日蛋糕 , 强剪枝
- poj 1190 生日蛋糕(dfs 剪枝)
- poj 1190 生日蛋糕(dfs, 剪枝)
- POJ 1190 生日蛋糕(深搜+剪枝)
- 深度搜索剪枝——生日蛋糕问题
- poj 1190 生日蛋糕(DFS+剪枝)
- POJ 1190 生日蛋糕(DFS:优化剪枝)
- poj 1190 dfs+剪枝(生日蛋糕)
- poj 1190 生日蛋糕(剪枝+深搜)
- POJ 1190 生日蛋糕 (dfs + 神剪枝)
- poj 1190 生日蛋糕(深搜+剪枝技巧)
- 单片机(七)__ds1302实时时钟
- JVM内存结构图解
- Handler消息机制和http网络请求
- [电影]《指环王》新老三部曲完全赏析(五军之战)
- 编程用等宽字体
- poj 生日蛋糕 搜索+剪枝
- 字符串反转技术推演过程
- 简单的c
- java 在线支付功能实现一
- SSH整合测试通过版+jar包
- 弹框
- 如何用U盘安装linux fadora系统
- 120闹钟AlarmManage
- 【技术分享】CVE-2016-6662:Mysql远程代码执行/权限提升技术分析正式版(9/13 10:47更新)