20.8.10 dfs+回溯

1.深搜回溯

深搜:对每一个单位枚举它的每一种可能
回溯:当前决策无解时返回上一次决策的状态

原题
在这里插入图片描述
最基本的枚举:每根火柴分别放在四个边,N根火柴共枚举4^N次,很可能超时

优化

        if(nums.size()<4) return false;//只有0-3根火柴,不可能拼成正方形
        int sum=0;
        for(auto x:nums) {
            sum+=x;
            t.push_back(0);
        }
        if(sum%4!=0) return false;//周长不是4的倍数,不可能
        tar=sum/4;
        //从大到小枚举每根火柴,可以去掉很多重复的情况
        sort(nums.begin(),nums.end(),[](int a,int b){return a>b;});
        if(nums[0]>tar) return false;//有单根火柴的长度比边长还长,不可能

下面开始进行搜索与回溯

每次只填充一条边,成功4次则说明可以

bool dfs(vector<int> nums,int i,int res,int n){
        if(n==0) return true;//已完成4次
        if(res==0) return dfs(nums,0,tar,n-1);//当前已完成,搜索下一次
        for(int j=i;j<nums.size();j++){//i代表上一层已经搜到的边,只需从i往后搜
            if(t[j]==0&&nums[j]<=res){
                t[j]=1;//t[j]=1代表j号火柴已使用
                if(dfs(nums,j,res-nums[j],n)) return true;//搜索下一个
                t[j]=0;//运行到这里说明选择j号的所有策略都已经失败,此时丢弃j号(回溯)
                //如果j号火柴被证明了不能使用,那么j号以后的、和j一样长的都不可能使用
                while(j+1<nums.size()&&nums[j+1]==nums[j]) j++;
            }
        }
        return false;
    }

代码采取的优化有:

进行搜索与回溯之前删掉的情况
从大到小按顺序搜索
使用变量i删去0-i的搜索项
一根火柴不能用,这根火柴后面的,一样长的都不能用

以下分别是几次优化后的提交结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值