• 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的来学习一下:

    链接地址

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

    柳暗花明又一村
  • 相关阅读:
    Git安装(操作篇)
    Git安装
    ES6基础练习
    SVN的安装与搭建及使用
    解决SVN文件不显示绿色小钩图标问题
    混入(mixin)
    ref属性与props配置项
    docker-compose部署 Mysql 8.0 主从模式基于GTID
    项目统一处理
    Docker Compose实战
  • 原文地址:https://www.cnblogs.com/ucandoit/p/8540812.html
Copyright © 2020-2023  润新知