POJ 1190 生日蛋糕
2016-07-20 08:47
344 查看
主函数尽量少写,都放到dfs里面去
#include<iostream> #include<cstdio> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int maxn=20+5; int minV[maxn],minA[maxn],maxV[maxn]; int area,bestarea=100000000; int m,t; int maxVforNRH(int n,int r,int h)//求出从n从到最上面一层的最大体积 { int ans=0; for(int i=n;i>=1;i--){ ans+=r*r*h; r--,h--; } return ans; } int dfs(int v,int n,int r,int h) { if(n==0){ if(v) return 0; else{ bestarea=min(bestarea,area); return 1; } } if(v<=0) return 7;//如果上升一层后,v为负数,则返回,原因是上一层的体积太大,超出题目所给体积要求 if(minV >v) return 2;//若从n层起的最小体积都大于所需要搭建的体积,则无法达到v,返回 if(minA +area>=bestarea) return 3;//如果现有的表面积加上从n层到最上面一层的最小表面积都大于最优表面,则返回 if(h<n||r<n) return 4;//h,r没上升一层最起码-1,若还有n层,但h,r却小于n,则不可能达到要求,返回 if(v>maxVforNRH(n,r,h)) return 5;//如果所要搭建的面积比可以搭建的最大面积还要大,则无法达到所求面积,返回 for(int i=r;i>=n;i--) { if(n==t) area=i*i; for(int j=n;j<=h;j++)//从小到大枚举是为了下面的break语句 { area+=2*i*j; int ok=dfs(v-i*i*j,n-1,i-1,j-1);//因为j是从小到枚举的,所以v是从大到小的,那么如果返回的是2,则说明所需搭建的最小体积都比要求的体积大,再往下枚举只会v越来越小,越不符合要求,所以下面可以break; area-=2*i*j; if(ok==2) break; } } return 6; } int main() { scanf("%d%d",&m,&t); minV[0]=0;minA[0]=0; for(int i=1;i<=t;i++){ minV[i]=minV[i-1]+i*i*i; minA[i]=minA[i-1]+2*i*i; } if(m<minV[t]) printf("0\n"); else{ int maxr,maxh; maxh=(m-minV[t-1])/(t*t)+1; maxr=sqrt((double)(m-minV[t-1])/t)+1; area=0; bestarea=(1<<30); dfs(m,t,maxr,maxh); if(bestarea==(1<<30)) printf("0\n"); else printf("%d\n",bestarea); } return 0; }
相关文章推荐
- iText生成pdf中文字体解决方案
- [Cloud Computing]Mechanisms: Physical Uplink
- python学习——使用模板
- 零基础学写界面
- 递推算法例题
- 商务通对话窗口左侧图片广告
- arm堆栈的增长方式
- SqlMap使用手册
- hdu 5179 beautiful number(打表,数位DP)
- Android如何在一个线性布局里完美显示两个listview啊?
- 为什么我觉得做在线教育平台的都不靠谱
- Git入门(4)-版本回退
- Codeforces Round #363 (Div. 2) C. Vacations(DP 动态规划)
- 用apache-cxf生成webservice客户端的时候报错Parameter: shead already exists for method
- redis 内存优化
- 反射 浅析
- redis 内存优化
- 从零入手体验指纹膜代打卡全过程
- Foundation: NSNotificationCenter
- 感悟