【DFS例题】等式

题目如下:
这道题依然是一道dfs(要求输出方案数很明显用dfs呐)
首先一个模板贴上来:

void dfs()//参数用来表示状态  
{  
    if(到达终点状态)  
    {  
        ...//根据题意添加  
        return;  
    }  
    if(越界或者是不合法状态)  
        return;  
    if(特殊状态)//剪枝
        return ;
    for(扩展方式)  
    {  
        if(扩展方式所达到状态合法)  
        {  
            修改操作;//根据题意来添加  
            标记;  
            dfs();  
            (还原标记);  
            //是否还原标记根据题意  
            //如果加上(还原标记)就是 回溯法  
        }  
    }  
}  

这道题目有些特殊,在我们已经把十个符号确定的时候,我们才能考虑是否需要把方案数++,也就是只有算出总和才能确定是否满足条件。
这道题目的深搜函数只需要一个参数(sum)也就是目前已经确定的符号数量,当它大于9,再进入下一层dfs时,就可以判断这种情况是否满足条件啦。
判断是否满足条件也很简单,我们用0表示这里没有符号,1表示有个加号,2表示有个减号,用num[i]表示第i-1和第i个数之间的符号。
于是就:

if(sum==10)
{
	int q=0,p;
	for(int i=1;i<=9;)
	{
		if(num[i]==1)flag=1;
		if(num[i]==2)flag=0;
		p=i;
		i++;
		while(!num[i]&&i<=9)
		{
			p=p*10+i;
			i++;
		}
		if(flag)q+=p;
		else q-=p;
	}
	if(q==n)cnt++;
	return;
}

注:flag表示是加法,!flag表示是减法。剩下的拓展方式就是这里放空,+,-,三种情况,参数全都是sum+1,dfs函数:

void dfs(int sum)
{
	if(sum==10)
	{
		int q=0,p;
		for(int i=1;i<=9;)
		{
			if(num[i]==1)flag=1;
			if(num[i]==2)flag=0;
			p=i;
			i++;
			while(!num[i]&&i<=9)
			{
				p=p*10+i;
				i++;
			}
			if(flag)q+=p;
			else q-=p;
		}
		if(q==n)cnt++;
		return;
	}
	num[sum]=1;
	dfs(sum+1);
	num[sum]=2;
	dfs(sum+1);
	num[sum]=0;
	dfs(sum+1);
	return;
}

完整代码:

#include<bits/stdc++.h>
using namespace std;
int n,cnt=0;
int num[10];//0.1+2-
bool flag;
void dfs(int sum)
{
	if(sum==10)
	{
		int q=0,p;
		for(int i=1;i<=9;)
		{
			if(num[i]==1)flag=1;
			if(num[i]==2)flag=0;
			p=i;
			i++;
			while(!num[i]&&i<=9)
			{
				p=p*10+i;
				i++;
			}
			if(flag)q+=p;
			else q-=p;
		}
		if(q==n)cnt++;
		return;
	}
	num[sum]=1;
	dfs(sum+1);
	num[sum]=2;
	dfs(sum+1);
	num[sum]=0;
	dfs(sum+1);
	return;
}
int main()
{
	cin>>n;
	num[1]=1;
	dfs(2);
	cout<<cnt<<endl;
	return 0;
}

坑点:num[1]初值要赋1!
ov.

posted @ 2019-07-08 16:43  摸鱼酱  阅读(180)  评论(0编辑  收藏  举报