zoukankan      html  css  js  c++  java
  • POJ 6048 泰国佛塔 【dfs搜索】【暴力大比拼】【北大ACM/ICPC竞赛训练】

     反正想清楚了就开始枚举吧,需要拿纸和笔推一些公式。

    我们想要m层的蛋糕有体积为N,那就枚举每一层蛋糕的半径和高度。其中第i层的蛋糕要比第i-1层的蛋糕半径和高度都大,第一层的蛋糕最小。

    发现dfs中要带四个参数,dfs(level,remainVolumn,maxRadius,maxHeight)代表用level层蛋糕要用掉remainVolumn这么多体积,其中第level层蛋糕最大半径是maxRadius,最高是maxHeight

    那怎么确定枚举的【半径和高度】的范围呢,我们考虑第m层(最底层)蛋糕的最大半径和最高高度。

    半径最大时是第m层用尽可能大的体积【第m-1至第1层的蛋糕都尽可能小==>第1层r=1,h=1;第2层r=2,h=2;第i层r=i,h=i】且高度尽可能小(也就是m)

    高度最高是用尽可能大的体积且半径尽可能小(也就是m)

    实现时我们可以处理出数组volumn[i]代表第i层到第1层所用最小体积

    搜索的话我们要尽可能剪枝,不然它指数级复杂度就TLE了。剪枝大体分为【可行性剪枝】和【最优性剪枝】,对于这道题来说可以有很多种剪枝姿势。

    1.剩下的蛋糕尽可能的大都用不掉remainVolumn这么多 【预测性可行性剪枝】

    maxV(level,maxRadius,maxHeight)<remainVolumn  //用level层蛋糕,第level层最大半径maxRadius,最高高度maxHeight时耗费的最多体积

    2.剩下的蛋糕尽可能小都超过remainVolumn这么多 【预测性可行性剪枝】

    volumn[level] > remainVolumn

    3. maxRadius或maxHeight小于当前的层数,那可预见往上摆的时候肯定有一层蛋糕枚举不出来 【预测性可行性剪枝】

    4. 目前已产生面积,加上之后level层的最小侧面积超过已经搜索到的答案【全局最优性剪枝】

    area + minArea[level] > ans //维护minArea[i]数组代表第i层到第1层蛋糕所用最小【侧面积】

    注意:所有上表面积都投影下来可以看成第m层蛋糕的上表面积

    因为剪枝这种东西时间复杂度没法分析,所以写了这么多剪枝,也不知道哪个剪枝剪掉的东西最多。所以就是暴力大比拼了。

     1 #include<iostream>
     2 #include<cmath>
     3 using namespace std;
     4 
     5 int volumn[25],minArea[25];//volumn[i]为第i层到第1层蛋糕所用最小体积
     6 int ans,n,m;                    //minArea[i]为第i层到第1层蛋糕所用【最小侧面积】 
     7 int area;//当前dfs状态所需要用的表面积
     8 
     9 int maxV(int level,int r,int h){//用level层蛋糕用的最多体积
    10                                 //在第level层的半径为r,高度为h的情况下
    11     int v=0;
    12     for(int i=0;i<level;i++){
    13         v+=r*r*h;
    14         r--; h--;
    15     }
    16     return v;
    17 }
    18 
    19 void dfs(int level,int remainVolumn,int maxRadius,int maxHeight){//用level层蛋糕去凑体积remainVolumn 
    20                                                     //这一层蛋糕可枚举的最大半径是maxRadius,最高高度是maxHeight    
    21 //    cout<<level<<" "<<remainVolumn<<" "<<maxRadius<<" "<<maxHeight<<endl;
    22     if(level==0){
    23         if(remainVolumn) return;
    24          ans=min(ans,area);
    25          return;
    26     }
    27     
    28     if( volumn[level]>remainVolumn ) return;//如果剩下的层数用最小的体积去摆都会超体积 == 预测可行性剪枝 
    29     if( area+minArea[level]>ans ) return;    //全局最优性剪枝 
    30     if( maxRadius<level || maxHeight<level ) return;//可行性剪枝
    31     if( remainVolumn>maxV(level,maxRadius,maxHeight)) return;//如果剩下的层数用尽可能大的体积去摆都用不完体积 == 预测可行性剪枝
    32     
    33     //剪完枝开始枚举第level层的【半径】和【高度】 
    34     for(int i=maxRadius;i>=level;i--){
    35         if( level==m ) area=i*i;//把底面积考虑上
    36         for(int j=maxHeight;j>=level;j--){
    37             area+=2*i*j;
    38             if( remainVolumn-i*i*j>=0) {
    39             //    cout<<"!!! "<<i<<" "<<j<<endl;
    40                 dfs(level-1,remainVolumn-i*i*j,i-1,j-1);
    41             }
    42             area-=2*i*j;
    43         }
    44     }
    45     
    46 }
    47 
    48 int main(){
    49     
    50     while( scanf("%d",&n)!=EOF ){
    51         cin>>m;
    52         ans=(1<<30);
    53     
    54         for(int i=1;i<=m;i++){
    55             volumn[i] = volumn[i-1] + i*i*i;
    56             minArea[i] = minArea[i-1] + 2*i*i;
    57         }
    58         area=0;
    59         
    60         //半径最大时是第一层蛋糕体积最大且高度最小 
    61         //1.什么时候体积最大
    62         //2.什么时候高度最小 
    63         int maxRadius = sqrt( (n-volumn[m-1])/m );
    64         
    65         //高度最高是第一层蛋糕体积最大且半径最小
    66         //第i层半径最小是i 
    67         int maxHeight = (n-volumn[m-1]) / (m*m) ;
    68         
    69         dfs(m,n,maxRadius,maxHeight);
    70         
    71         if(ans==(1<<30)) cout<<0<<endl;
    72         else cout<<ans<<endl;
    73     }
    74 
    75     
    76     return 0;
    77 }
  • 相关阅读:
    Adobe Creative Cloud for Win 解决:应用程序无法正常启动(0x0000022)。请单击“确定”关闭应用程序
    项目管理 PM 第六章 时间管理
    R for mac安装 无法争取安装Unable to install any packages 安装 r 里的 igraph 报错 ERROR: configuration failed for package ‘igraph’
    Python 相对路径的解决 “Unicode Error ”unicodeescape" codec can't decode bytes… Cannot open text files in Python 3
    GraphML入门教程
    文案——编辑——希腊字母Greek Alphabet
    Tensorflow入门
    安装Tensorflow及安装过程中的错误——ModuleNotFoundError: No module named 'tensorflow'
    基于 Virtualenv 的安装Tensorflow
    小程序--腾讯地图导航
  • 原文地址:https://www.cnblogs.com/ZhenghangHu/p/9371071.html
Copyright © 2011-2022 走看看