• POJ 1190 生日蛋糕


    经典搜索题!!送给自己的生日礼物!!!
    生日蛋糕

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)
    Total Submission(s) : 7   Accepted Submission(s) : 2
    Problem 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
    1002
     

    Sample Output
    68
     

    Source
    PKU
     



    AC代码:
     1 //Source Code
     2 
     3 //Problem: 1190        User: CKboss
     4 //Memory: 720K        Time: 16MS
     5 //Language: G++        Result: Accepted
     6 //Source Code
     7 
     8  
     9 #include <iostream>
    10 #include <cmath>
    11 
    12 #define INF 0xffff3f
    13 
    14 using namespace std;
    15 
    16 int n,m;
    17 
    18 int mind[22];
    19 int mins[22];
    20 double best=INF;
    21 
    22 void dfs(int k,int r,int h,int S,int D)
    23 {
    24     int i,j,ld;
    25     if(k==m)
    26     {
    27         if(D==n&&S<best) best=S;//不断替换最小值
    28 
    29         return ;
    30     }
    31 
    32     ld=n-D;//包括第K层到顶的体积
    33     for(i=r-1;i>m-k-1;i--)//枚举可能的半径,(比下面的大,比上面的小)
    34     {
    35         int maxh,ts=0,td;
    36         maxh=(ld-mind[m-k-1])/(i*i)+2;//判断最大高度
    37         if(maxh>h-1) maxh=h-1;
    38         for(j=maxh;j>m-k-1;j--)
    39         {
    40 
    41             td=ld-i*i*j;
    42             if(td<mind[m-k-1])  continue;//1号剪枝
    43 
    44             if(k==0)
    45                 ts=i*i+2*i*j;
    46             else
    47                 ts=S+2*i*j;
    48 
    49             if(ts+mins[m-k-1]>=best||ts+2*td/i>=best)  continue;//2号,3号剪枝(3号比较厉害)
    50 
    51             dfs(k+1,i,j,ts,D+i*i*j);
    52         }
    53     }
    54     return ;
    55 }
    56 
    57 
    58 int main()
    59 {
    60     cin>>n>>m;
    61 
    62     mind[0]=mins[0]=0;
    63     for(int i=1;i<=21;i++)
    64     {
    65         mind[i]=mind[i-1]+i*i*i;//从顶到 i 的累计最小体积
    66         mins[i]=mins[i-1]+2*i*i;//从顶到 i 的累计最小侧面积
    67     }
    68 
    69     dfs(0,sqrt(n)+1,n+1,0,0);//分别以半径为1,或高为1算最大的可能取值
    70 
    71     if(best!=INF)
    72         cout<<best<<endl;
    73     else
    74         cout<<0<<endl;
    75 
    76 
    77     return 0;
    78 }
  • 相关阅读:
    高精度乘除运算优化
    高精度除法
    高精度乘法
    期末考试
    P2341 [HAOI2006]受欢迎的牛[SCC缩点]
    P2002 消息扩散[SCC缩点]
    神奇搜索算法A*
    P3205 [HNOI2010]合唱队[区间dp]
    P4170 [CQOI2007]涂色
    P1220 关路灯[区间dp]
  • 原文地址:https://www.cnblogs.com/CKboss/p/CKboss.html
Copyright © 2020-2023  润新知