uva307 暴力dfs

小木棒的经典题目,以前做了,但是这次在uva上做,就tle了
1.选小木棒要先排列,从大到小
2.选小木棒用dfs做,如果当前长度小于要求长度,标记好当前比较的小木棒。
如果等于,则把比较木棒从1开始即可。

3.一直tle了很久,后来发现原因,还要一个减枝
如果在当前这个循环下,这个长度仍为0,说明找不到木棒和它了,(才会一层层递归回来使它回到0)那么错误在上一个递归就产生了,不要继续在这个里面循环,直接递归退回上一层。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=200;
int det[maxn];
bool vi[maxn];
int n;
int suc;
bool cmp(const int &a,const int &b){return a>b;}
void check(int num,int len,int th,int nowlen,int k)
{if(th>num){suc=1;return;}
    for(int i=k;i<=n;i++)
    {
        if(vi[i])continue;
        int nlen=nowlen+det[i];
        if(nlen==len)
        {vi[i]=1;
         check(num,len,th+1,0,1);
         if(suc)return;
         vi[i]=0;
         return;
        }
        if(nlen<len)
        {
        vi[i]=1;
        check(num,len,th,nlen,i+1);
        if(suc)return;
        vi[i]=0;
        while(det[i+1]==det[i])i++;
        }
    if(nowlen==0)return;
    }


}
int main(void)
{int sum;
    while(scanf("%d",&n)&&n)
    {sum=0;

        for(int i=1;i<=n;i++)
    {scanf("%d",&det[i]);
    sum+=det[i];
    }
    sort(det+1,det+n+1,cmp);
   // for(int i=1;i<=n;i++)printf("%d ",det[i]);printf("\n");
  //  printf("midgit=%d\n",midigit);

    for(int i=det[1];i<=sum;i++)
    {  if(sum%i)continue;
      //printf("i=%d\n",i);
        suc=0;
    memset(vi,0,sizeof(vi));
    check(sum/i,i,1,0,1);
    if(suc){printf("%d\n",i);break;}

    }


    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43235540/article/details/87835112
今日推荐