zoukankan      html  css  js  c++  java
  • HDU1258 Sum It Up DFS

      给定一个非递减的序列,要求从这些序列中找出一系列的数相加等于要求的数。这题的主要任务就是怎样去重。

      现分析如下:

      对于给定的两个非递减序列,A, B, C, D 用来映射各个数的位置,2(A) 1(B) 1(C) 1(D) 以及 2(A) 2(B) 2(C) 1(D), 要求求出和为3的表达式。 显然前面的序列递归下去会首先出现A+ B的组合,由于此时A+ B已经等于了3,所以递归就会回溯,此时会形成A+ C的组合,按照正常人的思维,这个解肯定是不能够取的,但是计算机有这么聪明吗?显然还是要我们来设计各种复杂的判断...... 转回正题,我们在递归时有一个属性就是递归的层数,而该题的求解就会与这个层数扯上关系,对于两个相邻且大小相等的点是要特殊考虑的,为什么呢,从上面给定的两个序列可以看出来,(重复就是因为这些相同的数字带来的),而且这个序列是已经相当于排好序的,这点同样很重要。那么对于相同的数(同样一定会是相邻的)在深入的递归过程中是可以取的(可以理解为此时的和还未等于要求值,相同的数仍有利用价值)。那么对于同一层的相同数呢,呵呵,这是不能够取的,为什么呢?首先对于该种组合的状态是不是已经搜索过了,唯一有变化的就是所剩数字的差别了,在此而言,就是相对与上一相同的状态少了这个数而已。这样可能比较抽象,就拿 2 2 2 1 这个序列来说吧,2与后面的2都不能组合,因为其值超过了限定值3,最后和1组合即 A+ D= 3,对于第二个2 即B, 此时B与A是同一层的递归下,如果取 B 的话,那么同当时取 A 就一样了,都是在接下来的序列中寻找和为(3- 2)的组合,然而上次的选择范围是(B, C, D)三个数,这次只剩下(C, D)两个数了,所以可以得出上次搜索的解一定包括这次去搜索得到的解,因此就出现重复了。证毕。

      代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    
    int t, n, num[105], rec[105];
    
    void DFS( int sum, int pos, int cnt, int &ans )
    {
    	if( sum== t )
    	{
    	    ans= 1;
    		for( int i= 1; i<= cnt; ++i )
    		{
    			printf( i== 1? "%d": "+%d", num[ rec[i] ] );
    		}
    		puts( "" );
    		return;
    	}
    	for( int i= pos+ 1; i<= n; ++i )
    	{ 
    	    if( num[i]!= num[i- 1]|| i== pos+ 1 )
    	    {
    	    // 前面的就是判定同一层不能计算相邻且大小相等的数,后面的处理不同层的相邻的相同的数
    		    if( t>= sum+ num[i] )
    		    {
    			    rec[cnt+ 1]= i;
    			    DFS( sum+ num[i], i, cnt+ 1, ans );
    		    }
    	    }
    	}
    }
    
    int main()
    {
    	while( scanf( "%d %d", &t, &n ), t| n )
    	{
    	    int ans= 0;
    	    num[0]= -1;
    		for( int i= 1; i<= n; ++i )
    		{
    			scanf( "%d", &num[i] );
    		}
    		printf( "Sums of %d:\n", t );
    		DFS( 0, 0, 0, ans );
    		if( !ans )
    		{
    		    puts( "NONE" );
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Perl语言入门笔记 第十六章 进程管理
    Perl语言入门笔记 第十五章 智能匹配与given-when结构
    Perl语言入门笔记 第十四章 字符串与排序
    Perl语言入门笔记 第十三章 目录操作
    Perl语言入门笔记 第十二章 文件测试
    artdialog
    trimend("asdas".tocharArry())
    jQuery.isEmptyObject() 函数详解 转
    ajax返回数据成功 却进入error方法
    为什么有些网站PING不通但又能访问.
  • 原文地址:https://www.cnblogs.com/Lyush/p/2135939.html
Copyright © 2011-2022 走看看