poj 1190 搜索
来源:互联网 发布:澳洲it专业认证 编辑:程序博客网 时间:2024/06/13 19:33
Description
7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体。
设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri > Ri+1且Hi > Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q = Sπ
请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。
(除Q外,以上所有数据皆为正整数)
设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri > Ri+1且Hi > Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q = Sπ
请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。
(除Q外,以上所有数据皆为正整数)
Input
有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。
Output
仅一行,是一个正整数S(若无解则S = 0)。
Sample Input
1002
Sample Output
68
Hint
圆柱公式
体积V = πR 2H
侧面积A' = 2πRH
体积V = πR 2H
侧面积A' = 2πRH
底面积A = πR 2
先找到底面最高的高度,和最大的半径,那么就需要知道最底层的最大体积,此时上面的每层肯定都是最小的,就从第一层开始每层都按最小的体积,表面积计算,每层都比上层多1,就是第一层高度1,半径1,第二层高度2,半径2等等依次
剪枝如下:
#include<stdio.h>#include<math.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3fusing namespace std;int n,m;int mina[30],minv[30];int area,minarea;int maxvfornrh(int t,int r,int h){ int v=0; for(int i=0; i<t; i++) v+=(r-i)*(r-i)*(h-i); return v;}void dfs(int v,int t,int r,int h) //剩余体积,层数, 最大的半径,高度{ if(t==0) { if(v!=0) return; else { minarea=min(minarea,area); //比较找到最小表面积 return; } } if(v<=0) //体积已用完,却没达到层数 return ; if(minv[t]>v)//剪枝3 剩余的每层都按最小的体积计算还是大于所剩体积 return; if(area+mina[t]>=minarea)//剪枝1 已有的表面积加上剩余的几层都按最小表面积计算还是大于已求得的最优解 return; if(h<t||r<t) //剪枝2 现在的半径或高度小于他所在的层数,就按每层相差最小1计算,则最后半径或高度就会减到负数 return ; if(maxvfornrh(t,r,h)<v) //剪枝4 剩下的每层都按最大的体积比所剩的体积还要小 return ; for(int rr=r; rr>=t; rr--) //从大到小 { if(t==m) //在最底层的时候加上底面的上表面积,即如果映射下来,全部圆柱的上表面积就可以看做最底部的上表面积,接下来只求侧面积即可 area=rr*rr; for(int hh=h; hh>=t; hh--) { area+=2*rr*hh;//侧面积 dfs(v-rr*rr*hh,t-1,rr-1,hh-1); area-=2*rr*hh; } }}int main(){ while(~scanf("%d%d",&n,&m)) { int maxh,maxr; mina[0]=0; minv[0]=0; for(int i=1; i<=m; i++) { mina[i]=mina[i-1]+i*i*2; //最小表面积 minv[i]=minv[i-1]+i*i*i; //最小体积 } if(minv[m]>n) //最小的体积比题目所给体积还要大 { printf("0\n"); continue; } else { maxh=(n-minv[m-1])/(m*m)+1; //得到的最大高度可能是小数,不如直接多加1,最大半径也如此 maxr=sqrt((n-minv[m-1])/m)+1; area=0; minarea=INF; dfs(n,m,maxr,maxh); if(minarea!=INF) printf("%d\n",minarea); else printf("0\n"); } } return 0;}
0 0
- poj 1190 搜索+剪枝
- poj 1190 搜索
- POJ 1190 生日蛋糕 搜索dfs
- poj 1190 生日蛋糕 隐式图搜索
- POJ 1190 生日蛋糕 搜索加剪枝
- POJ搜索题目总结
- POJ 2976 参数搜索
- 简单搜索1979@POJ
- 广度搜索-POJ 1753
- POJ搜索题目
- POJ - 1011 搜索剪枝
- POJ 搜索题
- poj搜索汇总
- poj 1411(搜索+剪枝)
- poj 2488( 搜索 )
- poj 3278( 搜索 )
- poj 3009( 搜索 )
- poj 3414( 搜索 )
- cocos2dx学习笔记(一)在cocos2dx 中使用spine骨骼动画
- openstack Glance概念
- 解决 Android 7.0 SQLiteCantOpenDatabaseException: unknown error (code 14)
- HDU2546 饭卡(01背包)
- Ubuntu无法访问windows分区
- poj 1190 搜索
- linux grep 查找 匹配 内容的文件 且 输出 文件名
- Spring Test 整合 JUnit 4 使用总结
- 宾大 计算机视觉课程
- 润乾报表V4超链接中对参数进行加密解密
- 16.04ubuntu安装后出现的N个问题
- Black Box poj 1442 优先队列
- mysql常用函数汇总(分享)
- socket编程代码示例(Head First系列)(单线程)