poj 1011

最近功力下降好多,肿么破。。。

凡是每次的第一根断木棍,都不能出现不return true的情况,如果出现了,直接false。强力剪枝。



 

#include<cstdio>

#include<vector>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

int a[100];

int sum,n;

int v[4005];

int all;

int one;

int vis[100];

int flag;

int j,o;

bool cmp(int a,int b)

{

    return a>b;

}

bool dfs(int p,int now,int s)

{

    if(s==one)

    {

        now++;

        if(all-now<=1) return true;

        s=0;

    }

    for(int i=1;i<=n;i++)

    {

        if(!vis[i]&&s+a[i]<=one)

        {

            if(!vis[i-1]&&a[i]==a[i-1]) continue;

            vis[i]=1;

            if(dfs(i+1,now,s+a[i])) return true;



            vis[i]=0;

            if(s==0) return false;      //强剪枝

        }

    }

    return false;

}

int main()

{

    while(scanf("%d",&n)&&n)

    {

        int maxn=0;

        sum=0;

        j=o=0;

        for(int i=1;i<=n;i++)

        {

            scanf("%d",&a[i]);

            sum+=a[i];

            maxn=max(maxn,a[i]);

        }

        sort(a+1,a+1+n,cmp);

        int top=0;

        for(int i=maxn;i<=sum;i++)

        {

            if(sum%i==0) v[top++]=i;

        }

        int ans=-1;

        for(int i=0;i<top;i++)

        {

            all=sum/v[i];

            one=v[i];

            memset(vis,0,sizeof(vis));

            flag=0;

            if(dfs(1,0,0))

            {

                ans=one;

                break;

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}


 

 

你可能感兴趣的:(poj)