poj 1190 生日蛋糕

来源:互联网 发布:淘宝摄影灯推荐 编辑:程序博客网 时间:2024/05/22 11:51

求!!!检!!!查!!!
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外,以上所有数据皆为正整数)

Input

有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。

Output

仅一行,是一个正整数S(若无解则S = 0)。

Sample Input
100
2

Sample Output
68


【分析】
主要是两个剪枝
最优性剪枝:已算得的答案(最小面积)减去蛋糕当前层以下的层的总面积是否小于上面的层所能构成的最小面积。如果小于则返回。
可行性剪枝:总体积减去蛋糕当前层以下的层的总体积是否小于上面的层所能构成的最小体积。如果小于则返回。
可我就是TLE啊啊啊啊啊

T到fai起啊啊啊啊救命啊啊啊求检查么么哒

【代码】

//poj 1190 生日蛋糕 #include<iostream>#include<cstdio>#include<cmath>#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;int n,m,R,ans=1e8;  //R:底面半径 int a[21],s[21],los[21],lov[21];inline void dfs(int v,int r,int h,int k){    int i,j;    lov[k]=lov[k-1]+r*r*h;    los[k]=los[k-1]+2*r*h;    v=v-r*r*h;    if(k==m)    {        if(v==0)          ans=min(ans,R*R+los[k]);        return;    }    if(v*2/r>=ans-los[k-1]) return;    if(v<0) return;    if(a[m]-a[k]+lov[k]>n)        return;  //体积剪枝     if(s[m]-s[k]+los[k]+R*R>=ans)        return;  //面积剪枝    fo(i,m-k,r-1)      fo(j,m-k,h-1)        dfs(v,i,j,k+1);}int main(){    int i,j,k;    scanf("%d%d",&n,&m);    for(i=m;i>=1;i--)    {        a[m-i+1]=a[m-i]+i*i*i;   //计算最小蛋糕体积的前缀和        s[m-i+1]=s[m-i]+2*i*i;   //计算最小蛋糕侧面积的前缀和     }    if(a[m]>n) {printf("0\n");return 0;}    fo(i,m,sqrt(n))  //枚举底面半径      fo(j,m,n/(i*i))  //枚举底层高       {          R=i;            dfs(n,i,j,1);      }    printf("%d\n",ans);}
0 0
原创粉丝点击