DFS求合法解个数问题

目录

例题

解题代码

缺陷

代码

 代码核心骨架

剪枝优化

DFS函数参数设计


例题

解题代码

缺陷

时间复杂度过高,即使剪枝优化后也只能得40%-50%左右的分数。

代码
#include<iostream>
using namespace std;
int wine = 2;
int ans = 0;

void DFS(int nowWine, int now, int nowlevel, int& nums,int& N,int&M,int n,int m);

int main() {
	
	int N = 0, M = 0;//N为店数 M为花数
	cin >> N >> M;
	
	int nums = N + M;
	DFS(2,1,1,nums,N,M,1,0);
	DFS(2,0,1,nums,N,M,0,1);
	cout << ans % 1000000007;
	return 0;
}

//合法的情况:本次的nowlevel等于nums并且此时nowWine正好等于0

//设计:1 为遇店 0 为遇花

void DFS(int nowWine, int now, int nowlevel, int& nums, int& N, int& M, int n, int m) {
	
    //这里出错了:不合法的情况讨论不完全:当遇店数或遇花数超出上限时,此时也不合法。
	if (nowWine==0 && now==0) {
		return ;
	}

	if (m>M || n>N) {
		return;
	}
	//当前序列到达最后层次
	if (nowlevel==nums) {
		/*if (nowWine == 0&&now==1) {
			ans++;
			return;
		}*/
		if (nowWine ==1&&now==0) {
			ans++;
			return;
		}
		else {
			return;
		}
	}

	if (now==1) {
		nowWine *= 2;
		
	}
	if (now == 0) {
		nowWine -= 1;
		
	}

	//程序进到这里进行更深层次的DFS

	DFS(nowWine,1,nowlevel+1,nums,N,M,n+1,m);

	DFS(nowWine,0,nowlevel+1,nums,N,M,n,m+1);

}
 代码核心骨架

递归+回溯+剪枝优化

剪枝优化

剪枝优化的作用:

将DFS递归过程中,不合法的情况剪掉,只留下合法的情况,同时节约了时间

剪枝代码:

if (nowWine==0 && now==0) {
		return ;
	}

	if (m>M || n>N) {
		return;
	}
	//当前序列到达最后层次
	if (nowlevel==nums) {
		/*if (nowWine == 0&&now==1) {
			ans++;
			return;
		}*/
		if (nowWine ==1&&now==0) {
			ans++;
			return;
		}
		else {
			return;
		}
	}

剪枝优化易错点

在剪枝时,一定要理解透题意,将所有的“枝”全部剪掉,即找出来全部不符合题意的情况,剪掉。

DFS函数参数设计

int nowWine当前李白所剩的酒数

int now:当前李白遇的是店还是花

int nowlevel:当前所处排列的具体元素位置

int& nums:每一种排列所拥有的元素个数

int& N:遇到的总店数

int& M:遇到的总花数

int n:截止到当前为止,所遇到的总店数

int m:截止到当前为止,所遇到的总花数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值