深搜的剪枝

深搜前面已经讲过,对于剪枝,就是把没必要的步骤进行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\n",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;
}

 

转载于:https://www.cnblogs.com/gongcheng456/p/10992774.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值