E - Red Polyomino 关于回溯 和爆搜

2024-08-27 18:52
文章标签 回溯 red polyomino

本文主要是介绍E - Red Polyomino 关于回溯 和爆搜,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这题就是爆搜。。虽然看似有2^(nn)的复杂度。。
但是实际上因为相连的限制。。种类非常有限。。样例8
8的就可以看出来。
所以就是爆搜而已。。

记录这题是因为。之前一直在思考回溯 到底和爆搜什么关系。。
目前算是阶段性的一个理解。。
回溯只不过是爆搜的一种方式而已。。
如果我们可以每层递归 都是拷贝。而不是引用。。实际上是不需要回溯的。

回溯只在于样本只有一份。就是传引用的时候。我们只有通过恢复现场。。来尝试其他的可能。
下面两个版本的写法。。就证明了这点。。
总结:回溯只不过是恢复现场的一种手法。。如果现场不需要恢复(每层都拷贝一份新的) 就不需要回溯🔥
而爆搜是一种枚举所有可能的手法。。分步X分类。比较经典的爆搜模型 就是完全二叉树 每个节点两种可能 选和不选。
题目链接

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128_t
#define ar array<int, 2>
#define arr array<int, 3>
int  n, m, k, inf = 1LL << 61, mod = 998244353;// 1e9+7;
const int N = 5e5 + 50;
int ans;
void dfs(vector<string>s) {int cnt = 0;for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j) {cnt += s[i][j] == 'o';}if (cnt == k) {ans++;return ;}for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j) {if (s[i][j] != '.')continue;if (cnt) {int d[5] {1, 0, -1, 0, 1};bool ok = 0;for (int c = 0; c < 4; ++c) {int x = i + d[c], y = j + d[c + 1];if (x >= 0 && y >= 0 && x < n && y < n && s[x][y] == 'o')ok = 1;}if (ok == 0)//就是旁边一定要有红色的。。因为相连continue;}s[i][j] = 'o';dfs(s);s[i][j] = '#';dfs(s);//我们传的是整个拷贝的s。这边就不需要回溯。return ;}
}
void solve() {cin >> n >> k;vector<string>a(n);for (auto&a : a)cin >> a;dfs(a);cout << ans;
};signed main() {ios::sync_with_stdio(false);cin.tie(0);cout << fixed << setprecision(15);
#ifdef DEBUGfreopen("../1.in", "r", stdin);
#endif//init_f();//init();//expr();// int T; cin >> T; while(T--)solve();return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128_t
#define ar array<int, 2>
#define arr array<int, 3>
int  n, m, k, inf = 1LL << 61, mod = 998244353;// 1e9+7;
const int N = 5e5 + 50;
int ans;
void dfs(vector<string>&s) {int cnt = 0;for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j) {cnt += s[i][j] == 'o';}if (cnt == k) {ans++;return ;}for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j) {if (s[i][j] != '.')continue;if (cnt) {int d[5] {1, 0, -1, 0, 1};bool ok = 0;for (int c = 0; c < 4; ++c) {int x = i + d[c], y = j + d[c + 1];if (x >= 0 && y >= 0 && x < n && y < n && s[x][y] == 'o')ok = 1;}if (ok == 0)//就是旁边一定要有红色的。。因为相连continue;}s[i][j] = 'o';dfs(s);s[i][j] = '#';dfs(s);s[i][j] = '.';//回溯本质上就多了这一步而已。。但是可以传引用。。!!!!return ;}
}
void solve() {cin >> n >> k;vector<string>a(n);for (auto&a : a)cin >> a;dfs(a);cout << ans;
};// 回溯只不过是为了还原现场而已。。如果传的不是引用。。。每个图都拷贝一份。那么根本不需要回溯!!!
//回溯只不过是爆搜的一种实现策略。。而已。。每个图都拷贝一份。那么根本不需要回溯!
// signed main() {ios::sync_with_stdio(false);cin.tie(0);cout << fixed << setprecision(15);
#ifdef DEBUGfreopen("../1.in", "r", stdin);
#endif//init_f();//init();//expr();// int T; cin >> T; while(T--)solve();return 0;
}

这篇关于E - Red Polyomino 关于回溯 和爆搜的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112492

相关文章

回溯——9.全排列

力扣题目链接 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 解题思路 问题建模:题目要求给出一个数组的所有排列组合,属于典型的全排列问题,这可以用回溯法来解决。回溯法通过递归的方式,依次将数组中的每个元素放入排列中,直到生成

风控系统之指标回溯,历史数据重跑

个人博客:无奈何杨(wnhyang) 个人语雀:wnhyang 共享语雀:在线知识共享 Github:wnhyang - Overview 回顾 默认你已经看过之前那篇风控系统指标计算/特征提取分析与实现01,Redis、Zset、模版方法。 其中已经介绍了如何利用redis的zset结构完成指标计算,为了方便这篇文章的介绍,还是在正式开始本篇之前回顾一下。 时间窗口 zset

Red Hat环境Git的下载和配置

安装git:         yum install git 设置git信息:              git config --global user.name "github"          git config --global user.email "github@gmail.com" 生成ssh key:         ssh-keygen -t rsa -C "gi

165-Stamps【回溯】

回溯 给h和k的意思是在k种邮票中选h个邮票 基本的连续邮资问题 15226160 165 Stamps Accepted C++ 0.062 2015-03-27 07:21:37 #include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 2

回溯——8.递增子序列

力扣题目链接 给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。 示例: 输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] 说明: 给定数组的长度不会超过15。数组中的整数范围是 [-100,100]。给定数组中

【代码随想录|回溯part04】

代码随想录|回溯part04 1、46.全排列2、47.全排列 II3.问题 总结 python 1、46.全排列 46.全排列 class Solution:def permute(self, nums):result = []self.backtracking

代码随想录算法训练营第十九天| 回溯理论、77. 组合、216. 组合总和Ⅲ、17. 电话号码的字母组合

今日内容 回溯的理论基础leetcode. 77 组合leetcode. 216 组合总和Ⅲleetcode. 17 电话号码的字母组合 回溯理论基础 回溯法也叫回溯搜索法,它是一种搜索的方式,而且只要有递归就会有回溯,回溯就是递归的副产品。 回溯说到底并不是什么非常高深的搜索方式,本质上仍然是穷举,穷举所有可能然后选择出我们要的答案。剪枝会使回溯法更加高效一点,但改变不了回溯本质就是穷举

算法打卡 Day28(回溯算法)-组合总数 + 组合总数 Ⅱ+ 电话号码的字母组合

文章目录 Leetcode 17-电话号码的字母组合题目描述解题思路 Leetcode 39-组合总数题目描述解题思路 Leetcode 216-组合总数 Ⅲ题目描述解题思路 Leetcode 17-电话号码的字母组合 题目描述 https://leetcode.cn/problems/letter-combinations-of-a-phone-number/descrip

【递归、回溯专题(三)】记忆化搜索题集

文章目录 1. 斐波那契数2. 不同路径2. 不同路径3. 最长递增子序列4. 猜数字大小II 1. 斐波那契数 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 给定 n

栈回溯

首先必须明确一点也是非常重要的一点,栈是向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,栈有栈底和栈顶,那么栈顶的地址要比栈底低。对x86体系的CPU而言,其中: ---> 寄存器ebp(base pointer )可称为“帧指针”或“基址指针”,其实语意是相同的。 ---> 寄存器esp(stack pointer)可称为“ 栈指针”。 要知道的是: ---