首页 > 其他分享 >童程OJ1508 小木棍 困难- 深搜/剪枝

童程OJ1508 小木棍 困难- 深搜/剪枝

时间:2023-11-03 20:26:10浏览次数:38  
标签:剪枝 maxx 童程 int len OJ1508 tot 木棍 长度

记忆步骤:
1.全局变量应该有木棍数组a和标记数组vis
主函数:
1.最小木棍长度len,标记是否有答案变量f
2.输入,并记录木棍的最大值maxx和全部长度sum
3.从大到小排序
4.遍历len从maxx到sum,如果sum刚好是len的倍数,那么证明有复原方案,进行深搜
dfs函数:
1.dfs(已经使用的木棍数量tot,当前复原木棍长度l,从第now根木棍开始)
2.如果标记f为真,结束搜索
3.如果使用木棍数量tot等于总数n并且此时木棍长度为0,证明所有木棍已经复原完毕,有结果,则标记f更新为1,结束搜索
4.记录上一次使用的长度为last等于-1,用于排除重复的复原方案
5.循环从第几根木棍开始,i从now到n
6.如果第i根木棍没有标记过,并且,当前长度l 加上 第i根木棍长度a[i] 小于等于目标木棍长度len,证明这根木棍能用
7.为了排除重复情况,先判断 l + a[i]是否等于last,如果等于那么是重复情况,则跳过
8.没有触发排重则把last记录为l + a[i]
9.标记第i根木棍
10.如果l+a[i]刚好等于len,证明刚好匹配,继续重新深搜dfs(木棍使用数量tot+1,当前长度为0,从第1根重新搜索)
11.否则说明l + a[i]还是小于len的,还要继续拼接木棍,继续从第i +1根开始搜索,dfs(木棍使用数量tot +1,当前长度则为l+a[i],从i+1根木棍开始搜索),这里的原因是因为我们从大到小排序了,所以继续拼接木棍,只能从下一根开始
12.回溯,清空第i根木棍标记
13.剪枝:如果l刚好为0,或者 l+a[i]刚好等于目标长度len,说明此时已经是最优情况了,继续搜索是没有更好的方案的,l + a[i]等于len很好解释,都匹配成功了没必要继续匹配;l = 0,拿样例的2+2+2来举例,就会发现l = 0是回溯到了最初的时候,而此时所有的5+1情况都匹配完了,很明显也是没有继续匹配的方案,所以也要结束,不然我们继续搜索下去,遇见的木棍都是已经标记过的,所以没有必要继续搜索了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3+10,inf = 0x3f3f3f3f;
int a[N],vis[N];
int len,n,f;
void dfs(int tot,int l,int now)
{
    if(f)return;
    if(tot == n && l == 0)
    {
        f = 1;return;
    }
    int last = -1;
    for(int i = now; i <= n; i++)
    {
        if(vis[i] == 0 && l + a[i] <= len)
        {
            if(l + a[i] == last)continue;
            last = l + a[i];
            vis[i] = 1;
            if(l + a[i] == len) dfs(tot + 1,0,1);
            else dfs(tot + 1, l + a[i], i + 1);
            vis[i] = 0;
            if(l == 0 || l + a[i] == len)break; //没有更好的结果 
        }
    }
}
int main()
{
    cin >> n;
    int maxx = 0,sum = 0;
    for(int i = 1; i <= n; i++)
    {
        cin >> a[i];
        maxx = max(a[i],maxx);
        sum += a[i];
    }
    sort(a + 1, a + 1 + n, greater<int>());
    for(len = maxx; len <= sum; len++)
        if(sum % len == 0)
        {
            f = 0;
            dfs(0,0,1);
            if(f)break;
        }
    cout << len;
    return 0;
}

 

标签:剪枝,maxx,童程,int,len,OJ1508,tot,木棍,长度
From: https://www.cnblogs.com/jyssh/p/17808331.html

相关文章

  • 4793: 虫食算 noip2004提高组T4 深搜/剪枝
    #include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1e3+10,inf=0x3f3f3f3f;charA[N],B[N],C[N];charwords[N];intcnt;charkeys[N];boolvis[N];intn;voidprint(){for(inti=0;i<n-1;i++)pri......
  • NOIP2003 传染病控制 深搜/剪枝
    思路题目大意是:把一棵树按深度分层,每一层断掉一条边,是剩下的节点数最小。其实,我们可以将问题转换为断掉的节点数最多。首先,贪心不可行,很容易被卡。因为数据只有300,直接搜索就行。搜索时一层一层搜,枚举断掉哪条边,并标记后代。#include<bits/stdc++.h>usingnamespacestd;......
  • C++U5-深度优先搜索-03(记忆化搜索、剪枝和优化)
    ......
  • DFS 剪枝
    DFS剪枝\(DFS\)是一种常见的算法,大部分情况下,很少会爆搜为正解的题目。因为\(DFS\)的时间复杂度特别高。我们可以先写一段dfs的伪代码intans=最坏情况,now;//now为当前答案voiddfs(传入数值){if(到达目的地){ans=从当前解与已有解......
  • 最优性剪枝,可行性剪枝,优化搜索顺序,排除等效冗余
    杨辉三角:  //https://www.luogu.com.cn/problem/P1118//最优性剪枝://由高中知识可得,abcd四个数符合杨辉三角的数相乘,即//res=a+3*b+3*c+d,前面的常数项也就是杨辉三角的数字//根据此结论,进行剪枝//由于暴力枚举全排列+部分剪枝不可过,所以要考虑方法性剪枝......
  • 力扣18:四数之和(双指针+剪枝)
    给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a],nums[b],nums[c],nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):0<=a,b,c,d <na、b、c 和 d 互不相同nums[a]+nums[b]......
  • YOLOv5:对yolov5n模型进一步剪枝压缩
    YOLOv5:对yolov5n模型进一步剪枝压缩前言前提条件相关介绍具体步骤修改yolov5n.yaml配置文件单通道数据(黑白图片)修改models/yolo.py文件修改train.py文件剪枝后模型大小参考前言由于本人水平有限,难免出现错漏,敬请批评改正。更多精彩内容,可点击进入YOLO系列专栏、自然语言处理专栏......
  • 搜索剪枝
    虽然我很懒,但集训期间还是强迫我自己写一下博客吧!搜索剪枝不搜不知道,我的搜索如同一坨shift。搜索没逻辑,剪枝随便捡,然后喜提withreturnvalue3221225725P1025数的划分非常简单的一道,数的拆分题题目描述将整数\(n\)分成\(k\)份,且每份不能为空,任意两个方案不相同(不......
  • 结构化剪枝 之 L1 剪卷积核 笔记
    论文:https://arxiv.org/pdf/1608.08710.pdf摘要CNN在各种应用中的成功伴随着计算和参数存储成本的显著增加。最近减少这些开销的努力包括在不损害原始精度的情况下修剪和压缩各个层的权重。然而,基于大小的权值修剪减少了完全连接层的大量参数,并且由于修剪后的网络中的不规则稀......
  • 模型压缩-剪枝算法详解
    近年来主流的模型压缩方法包括:数值量化(DataQuantization,也叫模型量化),模型稀疏化(Modelsparsification,也叫模型剪枝ModelPruning),知识蒸馏(KnowledgeDistillation),轻量化网络设计(LightweightNetworkDesign)和张量分解(TensorDecomposition)。其中模型剪枝是一种应用非常......