zoukankan      html  css  js  c++  java
  • 深搜的剪枝

    深搜前面已经讲过,对于剪枝,就是把没必要的步骤进行if特判剪枝,用好了可以大大的优化复杂度

    这里就根据两个例题来讲吧

    1440:【例题1】数的划分

    详情见代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    int n,k;
    int f[210][7];
    int main()
    {
        scanf("%d%d",&n,&k);
        memset(f,0,sizeof(f)); //f数组先初始化为0,
        f[0][0]=1;//但是第一个要为1,为了防止加来加去都是0
        for(int i=1;i<=n;i++)//总和的循环
            for(int j=i;j<=n;j++)//也是总和的循环,因为前面已经循环了i,所以j可以直接由i开始
            //循环两次是为了后面状态的处理做铺垫
                for(int x=1;x<=k;x++)//这是循环方案数
                {
                    f[j][x]=f[j][x]+f[j-i][x-1];//f[j][x]就是方案总数的最大值
                    //j-i是为了防止重复,比如说:1 1 5,1 5 1,5 1 1 这样的情况出现
                    //x-1就是上一个的最大值,是为了继承的
                }
        printf("%d
    ",f[n][k]);//输出最大值
        return 0;
    }

    1441:【例题2】生日蛋糕

    详情见代码

    include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<map>
    #include<string>
    #include<cstring>
    using namespace std;
    const int maxn=0x3f3f3f3f;
    const int minn=-0x3f3f3f3f;
    int n,m,ans,a[10086],b[10086];
    inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    /*
    体积V=πR2H
    侧面积A=2πRH
    底面积A=πR2
    */
    void dfs(int v/*已用体积*/,int s/*表面积*/,int p/*剩余层数 注意是剩余*/,int r/*半径*/,int h/**/) {
        if(p==0) { //如果已经搜没有剩余的层数了那就不用搜了!
            if (v==n&&s<ans)
                ans=s;
            return ;
        }
        if(v+b[p-1]>n)
            return ;//如果已用体积加上这层的最大体积大于了n那还搜个屁!
        if(s+a[p-1]>ans)
            return ;
        if(2*(n-v)/r+s>=ans)
            return; //当前的表面积+余下的侧面积>当前最优值那还搜个屁!
        for(int i=r-1; i>=p; i--) { //半径 
            if(p==m)
                 s=i*i;
            int pyyyyyy=min((n-v-b[p-1])/(i*i),h-1);
            
            for(int j=pyyyyyy; j>=p; j--) //
                dfs(v+i*i*j,s+2*i*j,p-1,i,j);
        }
    }
    int main() {
        n=read();
        m=read();
        cin>>n>>m;
        ans=maxn;
        a[0]=0;
        b[0]=0;
        for(int i=1; i<21; i++) {
            a[i]=a[i-1]+2*i*i;//i层的最大表面积
            b[i]=b[i-1]+i*i*i;//i层的最大体积   体积V=πR2H
        }
        dfs(0,0,m,n+1,n+1);//进行搜索
        //5个量的意思看上
        if(ans==maxn)
            cout<<0;
        else
            cout<<ans;
        return 0;
    }
  • 相关阅读:
    LeetCode70.爬楼梯
    LeetCode9.回文数
    LeetCode8.字符串转整数(atoi)
    LeetCode7.反转整数
    Docker深入浅出3-镜像管理
    Docker深入浅出3-容器管理
    Docker深入浅出2
    Docker深入浅出1
    Docker启动mysql的坑2
    各种常见兼容代码
  • 原文地址:https://www.cnblogs.com/gongcheng456/p/10992774.html
Copyright © 2011-2022 走看看