POJ1190[DFS经典]
来源:互联网 发布:sql truncate 外键 编辑:程序博客网 时间:2024/06/16 13:29
分蛋糕
题目链接
题目类型:DFS
题解:如果一开始我单独看到这道题,肯定不会朝搜索方向想。。。这里要积累一下思路。因为M,N的数据范围给定,且数据范围满足递减的要求,因此解空间有限,应该有搜索的想法,看看数据好像可以搜,考验剪枝水平;
爆搜方法,就是每次枚举100以内的半径,1000以内的高,搜索m层(m<=20),如果体积为刚好就存下结果,每一次取最小值;
剪枝部分,如果当前的圆柱半径与高度能够成的最大体积小于剩余体积,就结束;如果当前的面积大于之前搜到的最小面积,就结束;最后一个剪枝,不容易想到,如果到第k层时剩下第k到第M层的面积 2*Ri*Hi>2*Ri*Ri*Hi/Rk=2*Vi, 全部加起来就是 2*leftV, 所以 A+2*leftV>min 可以剪枝;
Code:
#include <iostream>#include <cstdio>#include<cstring>#include<algorithm>#include <string>#include <queue>#include <map>#define ll long long#define INF 0x3f3f3f3fusing namespace std;int N,M,ans=0;void dfs(int leftv ,int m , int A , int lastR , int lastH){ ///剪枝 if(A>ans&&ans)return ; if(leftv<0)return ; if( m * (lastR - 1) * (lastR - 1) * (lastH - 1) < leftv && m != M)return;///当前的极限体积小于剩下的体积 /// if(!m) { if(!leftv&&(A<ans||!ans)) { ans=A; } return; } for(int r = lastR - 1 ; r >= m ; r--)///还剩m层,因此最小半径为m { for(int h = lastH - 1 ; h >= m ; h--) { ///剪枝 if(A+2*leftv/r > ans && ans)///从100ms+优化到32ms return ; int curv=leftv-r*r*h; int curA=A+2*r*h; if(m==M)curA+=r*r;///如果是第一层,就加上底面积 dfs(curv , m - 1 , curA , r , h); } }}int main(){ scanf("%d%d",&N,&M); dfs(N,M,0,100,1000); cout << ans << endl; return 0;}
阅读全文
0 0
- POJ1190[DFS经典]
- poj1190 生日蛋糕 dfs
- POJ1190 生日蛋糕(DFS)
- Poj1190 生日蛋糕 DFS
- POJ1190->DFS&&剪枝
- poj1190 生日蛋糕 -dfs
- poj1190 生日蛋糕 dfs
- poj1190 经典深搜
- poj1190生日蛋糕(dfs+剪枝)
- poj1190 生日蛋糕 dfs神剪枝
- POJ1190 生日蛋糕(DFS剪枝)
- poj1190(dfs+剪枝)生日蛋糕
- POJ1190
- POJ1190
- POJ1190
- poj1190 神剪枝啊 生日蛋糕 (dfs)
- DFS:POJ1190-生日蛋糕(基础搜索)
- POJ1190 生日蛋糕 强大的dfs剪枝!!
- javascrip 学习
- Ubuntu 更新源地址列表及更改方法
- 算法导论 练习题 14.3-5
- 使用Jquery+EasyUI 进行框架项目开发案例讲解之四 组织机构管理源码分享
- abstract
- POJ1190[DFS经典]
- linux挂载u盘时显示只读系统
- java 银联,支付宝接口
- zookeeper-基于的Paxos算法
- Android下实现多线程断点下载
- Unity中判断目标在自己的哪个方位
- android 6之前版本判断应用是否有某个权限
- 获取两个#中间的内容 包含#
- import moviepy 报错