ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

蓝桥杯精选算法赛题——剪枝——剪格子

2022-03-20 11:03:48  阅读:209  来源: 互联网

标签:剪枝 题目 格子 赛题 蓝桥 搜索 BFS 3001.5501


这一节我们回顾一下我们之前学的DFSBFS
它们是暴力法的直接实现,能把所有可能的状态都搜出来,然后从中找到解。
不过,暴力法往往比较低效,把时间浪费在很多不必要的计算上。比如BFS 中的“跳蚱蜢”问题,从一个状态继续下一跳,有 4 种跳法,但是其中一些状态是不用跳的,因为是重复的。
在这个问题中,我们用了判重技术,它删去了这些不必要的跳法。判重极大地减少了计算量,它是剪枝技术的一种
剪枝是一个比喻:把不会产生答案的,或不必要的枝条“剪掉”。而剪枝的关键在于剪枝的判断:剪什么枝、在哪里减。剪枝是搜索常用的优化手段,常常能把指数级的复杂度,优化到近似多项式的复杂度。

  1. BFS的主要剪枝技术是判重,如果搜索到某一层时,出现重复的状态,就剪枝。
  2. DFS的剪枝技术较多,有可行性剪枝、最优性剪枝、搜索顺序剪枝、排除等效冗余、记忆化搜索等等:

可行性剪枝:对当前状态进行检查,如果当前条件不合法就不再继续,直接返回
搜索顺序剪枝:搜索树有多个层次和分支,不同的搜索顺序会产生不同的搜索树形态,复杂度也相差很大。
最优性剪枝:在最优化问题的搜索过程中,如果当前花费的代价已超过前面搜索到的最优解,那么本次搜索已经没有继续进行下去的意义,此时停止对当前分支的搜索进行回溯。
排除等效冗余:搜索的不同分支,最后的结果是一样的,那么只搜一个分支就够了。
记忆化搜索:在递归的过程中,有许多分支被反复计算,会大大降低算法的执行效率。用记忆化搜索,将已经计算出来的结果保存起来,以后需要用到的时候直接取出结果,避免重复运算,从而提高了算法的效率。记忆化搜索一般在DP中讲解。

一个题目中可以用到多种剪枝技术。
不过,这么多剪枝技术,也用不着记,总思路就是:减少搜索状态。说一千道一万,归根结底一句话:“搜索必剪枝、无剪枝不搜索”。如果你回顾前2节的BFS、DFS例题,可以发现,每一题都或多或少用到了剪枝。
接下来让我们回顾一下DFS 和 BFS 例题,看用了什么剪枝技术。
题目名称:迷宫 链接:https://blog.csdn.net/m0_51951121/article/details/122990741?spm=1001.2014.3001.5501题目大意:迷宫内每个点都有一个人,问多少人能走出来。 剪枝:记忆化搜索,如果一个点搜过,就不用再搜。
题目名称:全球变暖 链接:https://blog.csdn.net/m0_51951121/article/details/123300818?spm=1001.2014.3001.5501题目大意:有多少个岛被淹没。 剪枝:记忆化搜索,被检查过的点不用再检查。
题目名称:跳蚱蜢 链接:https://blog.csdn.net/m0_51951121/article/details/123316286?spm=1001.2014.3001.5501 题目大意:从一种状态跳到另一种状态,要多少步。 剪枝:判重。
题目名称:迷宫 链接:https://blog.csdn.net/m0_51951121/article/details/123300818?spm=1001.2014.3001.5501 题目大意:找到最短路径。 剪枝:最优性剪枝,找字典序最短的路。

不知不觉中已经用了这么多剪枝技巧。
下面我们再来一个题了解一下剪枝。

剪格子

题目描述

如下图所示,3×3 的格子中填写了一些整数。
请添加图片描述

我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 60。

本题的要求就是请你编程判定:对给定的 m×n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。

如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。

如果无法分割,则输出 0。

输入描述

程序先读入两个整数m,n 用空格分割 (m,n<10),表示表格的宽度和高度。

接下来是 n 行,每行 m 个正整数,用空格分开。每个整数不大于 104

输出描述

在所有解中,包含左上角的分割区可能包含的最小的格子数目。

样例输入

3 3
10 1 52
20 30 1
1 2 3

样例输出

3

答案

def dfs(x,y,c,s):
    global  ans
    dir = [[1,0],[0,-1],[0,1],[-1,0]]
    if  2*s>summ:
        return
    if  2*s==summ:
        if vis[0][0]:
            ans = c
        return
    vis[x][y] = 1
    for k in range(4):
        tx = x+dir[k][0]
        ty = y +dir[k][1]
        if tx>=0 and tx<n and ty>=0 and ty<m and not vis[tx][ty]:
            dfs(tx,ty,c+1,s+wzy[x][y])
    vis[x][y] = 0


m,n = map(int,input().split())
vis = [ [0,0,0,0,0,0,0,0,0] for _ in range(9)]
wzy = []
summ = 0
for i in range(n):
    wzy.append(list(map(int,input().split())))
    for k in range(m):
        summ += wzy[i][k]
dfs(0,0,0,0)
print(ans)

标签:剪枝,题目,格子,赛题,蓝桥,搜索,BFS,3001.5501
来源: https://blog.csdn.net/m0_51951121/article/details/123535080

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有