poj入门水题--深度搜索(dfs)题 1011,含各种剪枝,比较经典

深度搜索其实就是递归题,找到递归的条件最重要


1.1011 Sticks

解释:George 闲着无聊把一些长度木棒切成了小的棒子,现在他又想把木棒给复原,但是他不知道有几根棒,每根有多长。现在需要你帮助他复原。

解法:

比较经典的深搜题,里面还涉及到了剪枝还有一点小技巧:

1)因为小的棒子比较容易拼接成大的棒子,所以一开始要把大的放在前面。

2)因为是几根长度相同的,所以原先一根棒子的长度是总长度的约数。

3)因为是原先的棒子切成的,所以后来的一根棒子的长度<=原先棒子的长度。

4)如果拼接的长度大于了原先设定的棒子长度,说明这条路失败,可以剪掉。

上代码:

#include<iostream>
#include<algorithm>
#include<memory.h>
using namespace std;
#define MAX 100
int use[MAX],a[MAX],value,n;//n为棒子根数,sum为所有棒子长度和,value为所要求的最短单根棍子长
int sum;//定义全局变量sum


bool cmp(int a,int b){
    return a>b;
}//使数组a从大到小排列

bool dfs(int i,int left,int total)//试到了第几根,还要多少能拼接成这根木棒,拼接的总长度。
{ 
    int j;
    if(left==0)
    {
        total-=value;//寻找新棒子
        if(total==value)
            return 1;//如果只剩下value长度的没拼接,那么一定是能拼成这个长度的,这是剪枝1。
        if(total<value)
            return 0;//如果剩下的长度小于原先木棒的长度,那么一定拼不成了,可以返回失败了,这是剪枝2。
        for(i=0;i<n;i++)
            if(!use[i])
                break;	
            use[i]=1;//找到第一根没有用过的小木棒,置为用过,去做深搜。
            if(dfs(i+1,value-a[i],total))
                return 1;//成功的话,返回1
            use[i]=0;//不成功的话,重新置为0
            total+=value;//这个value可能不是合适的木棒长度。
            return 0;
    }
    
    else{
        for(j=i;j<n;j++)
        {
            if(a[j]>left||use[j])
                continue;//如果用过或者大于剩余长度,略过,此为剪枝3.
            if((a[j]==a[j-1])&&!use[j-1])
                continue;//如果前一根和后一根相等,且前一根没有用,那么表示这个长度之前就失败了,这次可以不要去深搜了,此为剪枝4.
            use[j]=1;					
            if(dfs(j+1,left-a[j],total))
                return 1;
            use[j]=0;				
        }
        return 0;
        
    }	
    return 0;
}








int searchfactor(int a[],int n){
int k=0;//k是判断是否找到了小于sum的因子
for(value=a[0];value<=sum/2;value++)
{
if(sum%value!=0)//若时间超了,去掉=
continue;
k=dfs(0,value,sum);
if(k!=0)
return value;

  }
  
    if(k==0)
    return sum;//若循环后没有则输出sum
}


int main()
{
    int i;
    while((scanf("%d",&n)!=EOF)&&n)
    {
        memset(use,0,sizeof(use));
        sum=0;
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        sort(a,a+n,cmp);
            printf("%d\n",searchfactor(a,n));
    }
    return 0;
}



    原文作者:DFS
    原文地址: https://blog.csdn.net/qq_17246605/article/details/53872076
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞