zoukankan      html  css  js  c++  java
  • C++ 洛谷 P1731 [NOI1999]生日蛋糕

    P1731 [NOI1999]生日蛋糕 一本通上也有。

    这TM是一道极其简单的深搜剪枝(DP当然可以的了,这里我只讲深搜)。

    首先圆柱公式:(有点数学基础都知道)
    V=πR2H
    S侧=π2RH
    S底=πR2

    状态描述

    用( i , Ri-1 , Hi-1 , Vi-1 , Si-1 )

    i表示打算去做第i层,

    已知第i-1层蛋糕的半径和高:Ri-1 ,Hi-1

    已知做完第i-1层蛋糕后剩下的蛋糕体积和获得的蛋糕表面积:Vi-1 , Si-1

    初始状态:(1,R0,H0,n,0)

    目标状态:(m+1,Rm,Hm,0,Sm)

    于是,我们要找到一条从初始状态到任意目标状态的路径,并且Sm最小。

    扩展的规则:

    ( i , Ri-1 , Hi-1 , Vi-1 , Si-1 )>>—>>( i+1,Ri,Hi,Vi,Si)

    满足:
    (1) Ri <Ri-1

    (2) Hi <Hi-1

    (3) Vi = Vi-1 - Ri* Ri* Hi

    (4) Si = Si-1 + 2 * Ri* Hi

    基本算法:

    dfs ( i , Ri-1 , Hi-1 , Vi-1 , Si-1 )

    {
    1)如果做好了m层,

                如果最终体积为0,刷新最小方案

                return;回去再做其他的方案

    2)枚举Ri,枚举Hi

    Vi = Vi-1 - Ri* Ri* Hi

    Si = Si-1 + 2 * Ri* Hi

    去做下一层dfs ( i+1 , Ri , Hi, Vi , Si ) 

    }

    基本代码:

    void Search (int i,int ri, int hi,int si,int vi,int num) 
    //num:记录上面还有num层没有堆
    {
    if(i>m)
    { if(vi==0)
    ans=min(ans,si);
    return;
    }
    for(int r=num;r<=ri-1;r++) //每层都比上层小,为整数,最小保证每层增加1
    {
    if(i==1) si=r*r;//把上表面算在第1层
    for(int h=num;h<=hi-1;h++)
    { 
    Search(i+1,r,h,si+2*r*h,vi-r*r*h,num-1);    
    }
    }
    }

     ^持续更新中……

  • 相关阅读:
    vsync信号产生与分发
    推荐看过不错的博客及网站
    证明质数有无数个
    242 Valid Anagram
    169 Majority Element
    快速排序--quicksort
    插入排序
    选择排序
    冒泡排序
    指针函数 函数指针 回调函数
  • 原文地址:https://www.cnblogs.com/mzyczly/p/10893786.html
Copyright © 2011-2022 走看看