• DFS+经典剪枝--poj1190--搭蛋糕(内含常见的剪枝类型分类)


    题目描述

    本地的重要启示:

    在接下来对每一个子问题进行搜索前可以先获得该子问题的搜索目标的极限,通过该极限可以判断对该子问题搜索出的解能否比当前最优解更优;或对该子问题搜索出的搜索目标能否满足要求,如果不能,就没必要了搜下去了,直接跳过对该子问题的搜索。该剪枝可以有效减小对某一子问题的搜索深度。

    这道题都说很经典,而我这种小白水平和感悟都不够,因此就不讲了,放上学习过程中对我有帮助的资源,供大家学习参考

    本题的最优化剪枝与可行性剪枝:

    下面是按gw老师的思路写的代码,看完别走,后面还有更好的:

    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <cmath>
    using namespace std;
    #define maxn 102
    
    const int inf=1<<30;
    
    int mina[30];         //仅侧面 
    int minv[30];
    int maxh,maxr;
    int minarea=inf;
    int n0;
    int area=0;
    
    int last_maxv(int n,int mr,int mh){
        int maxv1=0;
        for(int i=0;i<n;i++){
            maxv1+=(mr-i)*(mr-i)*(mh-i);
    //        maxv2+=(n-i)*(n-i)*(mh-1);
        }
        return maxv1;
    }
    
    void dfs(int v,int n,int mr,int mh){
        if(n==0){
            if(v) return;
            else{
                minarea=min(minarea,area);
                return;
            }
        }
        if(v<=0) return;
        if(v<minv[n]) return;
        if(mr<n || mh<n) return;
        if((area+mina[n])>=minarea) return;
        if( last_maxv(n,mr,mh)<v) return;
        for(int r=mr;r>=n;r--){
            if(n==n0) area=r*r;
            for(int h=mh;h>=n;h--){
                area+=2*r*h;
                dfs(v-r*r*h,n-1,r-1,h-1);
                area-=2*r*h;
            }
        }
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        minv[0]=0;mina[0]=0;
    
        int v;
        cin>>v>>n0;
        for(int i=1;i<=n0;i++){
            mina[i]=2*i*i+mina[i-1];
            minv[i]=i*i*i+minv[i-1];
        }
        if(v<minv[n0]) {
            cout<<0<<endl;
            return 0;
        }
        maxh=(v-minv[n0-1])/(n0*n0)+1;
        maxr=sqrt(double(v-minv[n0-1])/n0)+1;       //用double防止小数点后面的丢失
    //    cout<<maxh<<' '<<maxr;
        dfs(v,n0,maxr,maxh);
    //    cout<<"Loved"<<endl;
        if(minarea==1<<area)
        cout<<0<<endl;
        else cout<<minarea<<endl;
        return 0;
    }

    提交之后发现我的代码要跑47ms,但是很多人的只需要0ms,而且内存占用更小,于是找到一份0ms的来学习一下:

    链接地址

    这个剪枝讲的不错,代码注释清楚:链接

    柳暗花明又一村
  • 相关阅读:
    Kali 查看系统信息的一些命令及查看已安装软件包的命令
    mysql_对于DQL 的简单举例
    java简单分析LinkedList
    java_简单解析ArrayList_iterable
    java_随机密码
    rsync 服务基础配置讲解
    DNS服务器的基础
    NFS服务器配置
    DHCP服务器配置
    VSFTP 配置详解,附带例子
  • 原文地址:https://www.cnblogs.com/ucandoit/p/8540812.html
Copyright © 2020-2023  润新知