hdu 1455 poj 1011 sticks

dfs+剪枝,一道很好的题目,只是我不会写,求教了别人才写对了,发现以前写过的。。我勒个去,但以前那条过不去的。。。安慰。。

  剪枝部分有很多。。最大就是搜索的时候如果发现k这个木条可以用的时候,递归下一次搜索的时候就应该从k+1开始搜索而不是0开始从新搜索,否则他会重复的搜索k前面一些之前搜索失败的木棍,这样就浪费了很多时间了。。

  还有就是要先排序再搜索,先搜索大木条,因为他的限制的比较好,搜索出来的情况会容易控制点。。。

View Code
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#define min(a,b) a<b?a:b
int s[70],n;
int v[70],asum;
int cmp(const void*x,const void*y)
{
    return *(int *)y-*(int *)x;
}
int dfs(int len,int pre,int sum,int ll)
{
    int i;
    if(pre==len)
    {
     if(sum+1==asum/len)
        return 1;
     for(i=0;i<n;i++)
         if(!v[i])
         {
           v[i]=1;
           if(dfs(len,s[i],sum+1,i+1))
               return 1;
           {
                v[i]=0;
                while(s[i]==s[i+1])
                    i++;
           }
           break;
         }
    }
    for(i=ll;i<n;i++)
        if(!v[i]&&pre+s[i]<=len&&s[i])
        {
            v[i]=1;
            if(dfs(len,pre+s[i],sum,i+1))
                return 1;
            else
            {
                v[i]=0;
                while(s[i]==s[i+1])
                    i++;
            }
            
        }
    return 0;
}
int main()
{
   int i,ans;
   while(scanf("%d",&n),n!=0)
   {
       int min=100000;
       asum=0;
       for(i=0;i<n;i++)
       {
           scanf("%d",&s[i]);
           asum+=s[i];
           if(s[i]<min)
               min=s[i];
       }
       qsort(s,n,sizeof(int),cmp);
       memset(v,0,sizeof(v));
       for(i=n;i>=1;i--)
           if(asum%i==0&&asum/i>=min&&s[0]<=asum/i&&dfs(asum/i,0,0,0))
           {
               ans=asum/i;
               printf("%d\n",ans);
               break;
           }
   }
           
return 0;
}

posted on 2012-07-24 14:04  usp10  阅读(221)  评论(0编辑  收藏  举报

导航