POJ 1011 Sticks DFS+剪枝
传送门: http://poj.org/problem?id=1011
题目大意:
给出一些棍棒的长度,求把他们拼接成长度一样的若干棍棒的最小长度(全部用完),
经典的DFS+ 剪枝
和别人的代码一样的剪枝为啥我的172MS人家32MS甚至16 为啥。。。。。。。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define F(i,R) for(int i=0;i<R;i++) int a[64+2]; bool used[64+2]; int n; bool cmp(const int &a,const int &b) { return a>b; } bool dfs(int cur,int sum,int target) //已经拼成的个数 现在拼的长度 目标长度 { if(cur==n && sum==target) return true; if(sum==target) sum=0; for(int i=0;i<n;i++) { if(used[i]==true) continue; if(sum+a[i] > target) //剪枝2,如果当前拼接的大于目标那么没必要继续了 continue; used[i]=true; if(dfs(cur+1,sum+a[i],target)) return true; used[i]=false; if(sum==0) //最重要的剪枝!如果找不到和当前匹配的那么直接跳出循环。 break; while(a[i] == a[i+1])//剪枝3,如果当前的棍子不满足那么和它相等的也不行 i++; } return false; } int main() { while(scanf("%d",&n),n) { int sum=0; F(i,n) { scanf("%d",&a[i]); sum+=a[i]; } sort(a,a+n,cmp); int i; for(i=a[n-1];i<=sum;i++) { if(sum % i !=0) continue; //剪枝1 memset(used,0,sizeof(used)); if(dfs(0,0,i)) break; } printf("%d\n",i); } }
新 blog : www.hrwhisper.me