POJ1011【判重剪枝】

来源:互联网 发布:淘宝评价过期怎么办 编辑:程序博客网 时间:2024/05/08 12:09
题意:
给你一堆棒子,这些棒子是你从一堆一样的棒子折断而来的,
现在你忘记了是从那一堆一样的棒子的长度,让你写一个程序,求最短的长度。
思路:
首先这个棒长肯定是和的约数,且大于最大值。
然后是sort一下棒子长度从大到小(我也不知道为啥可行)
最后就是一个判重剪枝:
注意判重剪枝,是对相同情况的剪枝,这个相同情况就是要非常相同!

这里代码那个!vis[i]很有体会啊;

//#include <bits/stdc++.h>#include<iostream>#include<cstdio>#include<queue>#include<math.h>#include<string.h>#include<algorithm>using namespace std;typedef long long LL;typedef pair<int,int> PII;int n,a[65];int multi[550],sum;bool cmp(int x,int y){    return x>y;}int solve(int x,int temp){    int num=0;    int q=(int)sqrt((double)x);    for(int i=1;i<=q;i++)        if(x%i==0){            if(i>=temp)                multi[num++]=i;            if((x/i)>=temp)                multi[num++]=x/i;        }        return num;}bool vis[65];int flag;void DFS(int num,int len,int cur){    if(flag==1)        return;    if(num*len==sum)    {        flag=1;        return;    }    int tempcur=cur,tempnum=num;    if(cur==0)    {        int  x=1;        while(vis[x])            x++;        cur+=a[x];        if(cur==len)        {            cur=0;            num++;        }        vis[x]=1;        DFS(num,len,cur);        vis[x]=0;        cur=tempcur;        num=tempnum;        return;    }    for(int i=1;i<=n;i++)    {        if(vis[i]||cur+a[i]>len) continue;        if(i>1&&a[i-1]==a[i]&&!vis[i-1]) // !vis[i-1]要保证相同情况;            continue;        cur+=a[i];        if(cur==len)        {            num++;            cur=0;        }        vis[i]=1;        DFS(num,len,cur);        vis[i]=0;        num=tempnum;        cur=tempcur;    }}int main(){    while(scanf("%d",&n)&&n){        int tmx=0;        sum=0;        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            sum+=a[i];            tmx=max(tmx,a[i]);        }        sort(a+1,a+n+1,cmp);        int num=solve(sum,tmx);        sort(multi,multi+num);        flag=0;        for(int i=0;i<num;i++)        {            memset(vis,0,sizeof(vis));            DFS(0,multi[i],0);            if(flag==1)            {                printf("%d\n",multi[i]);                break;            }        }    }    return 0;}


0 0
原创粉丝点击