簡單深搜(搜索所有和的可能)

題目來源:[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了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章