zoukankan      html  css  js  c++  java
  • POJ-1190-生日蛋糕-DFS(深搜)-枚举-多重剪枝

    题目链接:

    这个题目非常好,有难度;能够好好的多做做;

    #include<iostream>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<map>
    #include<cmath>
    #include<stack>
    #include<set>
    #include<vector>
    #include<algorithm>
    #define LL long long
    using namespace std;
    int MinArea=1<<30;  //  存最优表面积。
    int MinV[30];       //  存第一层到该层最小体积;
    int MinA[30];       //  存第一层到该层最小面积。
    int N,M;            //  体积,层数。
    int area=0;         //  存增在搭建的表面积;
    int MaxV(int n,int r,int h)     //  当有n层时。能够有的最大体积;当中r为最大半径,h为最大高度;
    {
        int v=0;
        for(int i=0;i<n;i++) v+=(r-i)*(r-i)*(h-i);
        return v;
    }
    void dfs(int v,int n,int r,int h)
    {
        if(n==0){           //  说明一种情况搭建层数已经完毕。
            if(v) return;
            else{
                MinArea=min(MinArea,area);      //  能够搭建,则更新最优解。
                return;
            }
        }
        if(v<=0) return;                    //  体积不够,退出。
        if(MinV[n]>v) return;               //  搭建n层的最小体积比提供的体积大。即无法搭建。退出;
        if(area+MinA[n]>=MinArea) return;   //  当前搭建表面积加上前n层最小的表面积比最优解更大。则能够退出。
        if(h<n||r<n) return;                //  最大半径,或者最大高度比层数还要多。则就说明已经无法继续搭建了。
        if(MaxV(n,r,h)<v) return;           //  这n层能够搭建的最大体积都比提供的体积要小,说明无法按要求搭建;
        for(int rr=r;rr>=n;rr--){       //  从最大半径開始枚举搜索。
            if(n==M) area=rr*rr;        //  底面积;
            for(int hh=h;hh>=n;hh--){   //  从最大高度開始枚举。
                area+=2*rr*hh;          //  搭建的面积更新;
                dfs(v-rr*rr*hh,n-1,rr-1,hh-1);
                area-=2*rr*hh;          //  回溯;
            }
        }
    }
    int main()
    {
        while(~scanf("%d%d",&N,&M)){
            MinV[0]=0;
            MinA[0]=0;
            for(int i=1;i<=M;i++){
                MinV[i]=MinV[i-1]+i*i*i;                    //  前i层最小体积;
                MinA[i]=MinA[i-1]+2*i*i;                    //  前i层最小面积;
            }
            if(MinV[M]>N) printf("0
    ");
            else{
                int MaxH=(N-MinV[M-1])/(M*M)+1;             //  底层最大高度。
                int MaxR=sqrt(double(N-MinV[M-1])/M)+1;     //  底层最大半径;
                int area=0;
                MinArea=1<<30;
                dfs(N,M,MaxH,MaxR);
                if(MinArea==1<<30)  printf("0
    ");
                else  printf("%d
    ",MinArea);
            }
        }
        return 0;
    }


     

  • 相关阅读:
    java中如何获得系统路径!(项目的路径)
    纯DOS学习笔记
    Ubuntu 初始配置
    原码、反码、补码
    几个小程序
    数据类型字符串、字节
    rdesktop方法(Linux to Windows)
    Python语言说明
    Manjaro 初始配置anacondapycharmopencvtensorflow
    【转】谈谈MATLAB中cell数据类型
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6782291.html
Copyright © 2011-2022 走看看