简单深搜(搜索所有和的可能)

题目来源:[NWPU][2014][TRN][4]搜索 I题

http://vjudge.net/contest/view.action?cid=49557#problem/I

作者:npufz

题目:给出一个不上升的正整数序列,再给定一个值SUM,在给定的那列数字中找出所有的和为SUM的数字组合,然后对所有组满足和为SUM的组合,进行不升序排列,然后按照从起始位一次降低的情况输出所有的组合

例如:SUM=4 有 10个数字,:4,4,3,3,2,2,2,1,1,1

输出为:4;

                         3+1;

                         2+2;

                         2+1+1;

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int  vis[15]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
int   jl[15]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
bool flag;
int  cs;
void  print(int sum)
{   bool fir;
    fir=true;
    int j;
    if(cs==1)
    { j=0;
    if(flag)
    {printf("Sums of %d:\n",sum);flag=false;}
    for(int i=0;i<15;i++)
    {   if(vis[i]!=-1)
        jl[j++]=vis[i];
        if(fir==true&&vis[i]!=-1)
          {
        printf("%d",vis[i]);fir=false;
                               }
      else if(vis[i]!=-1)   printf("+%d",vis[i]);
      }
     cout<<endl;cs=-1;
     }
     else
        { bool flag2=false ,flag1=true;j=0;
          int m=0;
        for(int i=0;i<15;i++)
        {
           if(vis[i]!=-1)
           {  if(vis[i]>jl[m])  {flag1=false;break;}
              if (vis[i]<jl[m]) break;
              m++;
              }
         }
       for(int i=0;i<15&&flag1;i++)
        {
            if(vis[i]!=-1)
                {   if(vis[i]!=jl[j])
                    {jl[j]=vis[i];flag2=true;}
                     j++;
                }
        }
        if(flag2&&flag1)  { flag2=false;
    for(int i=0;i<15;i++)
    {
        if(fir==true&&vis[i]!=-1)
          {
        printf("%d",vis[i]);fir=false;
                               }
      else if(vis[i]!=-1)   printf("+%d",vis[i]);
      }
     cout<<endl;
     }}}
bool  dfs(int sum, int num ,int i,int sum1,int a[] )
{
    if(sum>=sum1 &&i<=num)
    {    if(sum==sum1)  print(sum);
         vis[i]=a[i];
         dfs(sum,num,i+1,sum1+a[i],a);
         vis[i]=-1;
         dfs(sum,num,i+1,sum1,a);
         vis[i]=-1;
    }
    else return true;
}
using namespace std;
int main()
{  int a[15],sum,num,i;
    while(scanf("%d%d",&sum,&num),num)
    { for(i=0;i<num;i++)
      scanf("%d",&a[i]);
      flag=true;cs=1;
      dfs(sum,num,0,0,a);
      if(flag) printf("Sums of %d:\nNONE\n",sum);
}
return 0;
}

反思:主要是对深搜理解的有点不对劲,在控制递归的条件上有失误,在改正之后,发现输出是个大问题,我程序的解空间是一个很每个元素加进去与不加进去的一个树,复杂度很高不说,一旦所给的序列中出现重复的元素,那没就会搜索到很多的重解,去重复是个很关键的东西,一开始想的太简单了,有漏洞,就WA了,改了后就A了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值