zoukankan      html  css  js  c++  java
  • 【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.

    个人博客地址: www.moyujiang.com 或 moyujiang.top
  • 相关阅读:
    删除表空间的时候遇到的问题:ORA-02429: 无法删除用于强制唯一/主键的索引
    删除
    Activity中使用getSystemService获得系统服务
    用多线程实现反应灵敏的界面(Java)
    用数组实现3个栈之固定分割(Java)
    Android小知识点20条
    Android数据库中数据文件的导出与查看
    MFC中使用CSplitterWnd分割窗口后设置视图大小的问题
    MFC中,通过preCreateWindow函数无法设置视图样式(包括窗口的大小)
    6:Node.js 路由
  • 原文地址:https://www.cnblogs.com/moyujiang/p/11167745.html
Copyright © 2011-2022 走看看