POJ 1011木棒

来源:互联网 发布:linux 显示下载速度 编辑:程序博客网 时间:2024/05/02 04:45

if(stick[i]==temp||temp==len) break;这个剪枝的理解:

stick[i]==temp:

表示前面的N根木棒拼接成功了,但是后面剩下的拼接失败了,说明就要去掉以前恰好合适的木棒,而用其他的小于等于它的其他木棒来代替他,

其他成功代替它的木棍,都是小于等于它的,它们拼接的自由度更大都使剩下的木棍拼接失败了,换了,最终还是会失败,所以直接剪枝了;

temp==len:

开始拼接一根新的木棍时,第一根肯定不会小于其他没有用过的木棍了,(由于降序排序了的,并且每次都是从长的开始找起的),那么这根最长

的和剩下的所有的木棍拼接都失败了,但是最终要拼接成功,那么这个最长的木棍是一定要被用掉的,但是从目前的状况来看无论如何也用不掉了

所以拼接最终会失败的,因此后面的都不用尝试了。

直接跳出循环,返回false。

以下是AC代码:

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<cstdlib>#include<queue>#define MAXN 100#define LL long long intusing namespace std;int cmp(const void *a,const void *b){    return *(int *)b-*(int *)a;}int stick[70];bool use[70];bool is_original(int totalsticks,int unusedsticks,int temp,int len){    if(unusedsticks==0&&temp==0) return true;    if(temp==0) temp=len;    for(int i=0;i<totalsticks;i++){        if(use[i]==false) continue;        if(stick[i]>temp) continue;        use[i]=false;        if(is_original(totalsticks,unusedsticks-1,temp-stick[i],len)){            return true;            }        use[i]=true;        if(stick[i]==temp||temp==len) break;    }return false;}int main(){    int n;    while(~scanf("%d",&n),n){        int sum=0;        memset(use,true,sizeof(use));        for(int i=0;i<n;i++){            scanf("%d",&stick[i]);            sum+=stick[i];        }        qsort(stick,n,sizeof(stick[0]),cmp);        int len=stick[0];        for(int i=len;i<=sum;i++){            if(sum%i!=0) continue;            if(is_original(n,n,0,i)){                printf("%d\n",i);                break;            }         }    }return 0;    }