【蓝桥杯】2019国赛B组 101串(dfs剪枝)

“01串”指的是由0和1组成的字符串。
蒜头君是火箭少女101的铁杆粉丝,他想知道:
长度为30的01串中,有多少串含有子串“101”.

思路分析:

其实就是用dfs枚举2^30种情况。如果纯暴力就是枚举完每一个长度为30的字符串里再加一个循环判断里面是否含有子串"101"。虽然此题没有时间限制,只要填结果,但是我们要有一颗优化的心!

在枚举的过程中,即字符串长度<=30中,如果已经发现有101串,那么后面就不需要枚举了。比如说,拿长度为4举例。1010 1011前3位已经有“101”了,那么第四位是什么已经无关紧要。也就是说,如果当前cur已经满足"101",那么cur后面剩下的数都不需要再枚举了,因为它们不管什么结果这个字符串都已经含有"101". 因此后面剩下n-cur-1个数,有pow(2,n-cur-1)种情况。cnt直接加上就行。
下面上代码:

#include <iostream>
#include <cmath>
using namespace std;

long long a[40], cnt;
long long n = 30;

void dfs(int cur)
{
	if(cur >= n)	
	{
		return;
	}
	if(a[cur] == 1 && a[cur-1] == 0 && a[cur-2] == 1)
	{
		cnt+=pow(2,n-cur-1);
//		for(int i = 0;i <= cur;i++) cout<<a[i]<<" ";
//		cout<<endl<<cnt<<endl;
		return;
	}
	a[cur+1] = 0;
	dfs(cur+1);
	a[cur+1] = 1;
	dfs(cur+1);
}

int main()
{
	dfs(-1);
	cout<<cnt<<endl;
}

答案:1046810092

### 蓝桥杯中的DFS算法应用 在蓝桥杯中,深度优先搜索(Depth First Search, DFS)是一种常见的解决复杂问题的方法之一。对于特定场景下的优化和实现细节尤为重要。 #### 使用DFS求解迷宫类问题 当面对类似于机房布局的问题时,可以将整个空间抽象成图结构来处理。通过定义节点之间的连接关系,利用DFS遍历所有可能路径寻找最优解[^1]。 ```cpp bool dfs(int x, int y){ if (x == endX && y == endY) return true; // 到达终点条件 visited[x][y] = true; const int dx[] = {0,-1,0,1}; const int dy[] = {-1,0,1,0}; for(int i=0;i<4;++i){ int nx=x+dx[i], ny=y+dy[i]; if(nx>=0&&nx<n&&ny>=0&&ny<m&&!visited[nx][ny]&&maze[nx][ny]!='#'){ if(dfs(nx,ny)) return true; } } visited[x][y]=false; // 回溯操作 return false; } ``` 此代码片段展示了如何在一个二维网格上执行DFS以查找从起点到指定位置的有效路线。`visited[][]` 数用于标记访问状态防止重复探索相同地点;而 `dfs()` 函数则递归地尝试向四个方向移动直到找到目标或穷尽选项。 #### 剪枝技巧提升效率 为了提高DFS性能,在实际比中经常采用剪枝技术减少不必要的计算量。例如提前终止不可能成功的分支、记忆化存储已经计算过的子问题结果等方法都可以显著加快运行速度并节省资源消耗。 #### 数据结构的选择影响 值得注意的是数据结构的选择也会极大地影响程序的表现。正如提到的那样,在某些情况下使用更高效的数据容器代替标准库提供的关联式容器能够带来意想不到的效果——比如这里建议避免使用 `unordered_map` 来解决问题以免遇到性能瓶颈。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值