poj 1011 dfs剪枝
参考了http://blog.csdn.net/xuezhongfenfei/article/details/8523380
//poj 1011 dfs #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n,st[100]; int ans,m; int used[100],num[100],startnum[100]; bool cmp(int a,int b) { return a>b; } int dfs(int len,int k,int ret) { if(k==n && ret==0) return len; if(ret==0) ret=len;//已拼成一个 int i; for(i=0;i<n;i++){ if(!used[i] && st[i]<=ret){ used[i]=1; if(dfs(len,k+1,ret-st[i])) return len; used[i]=0; //搜索失败 复原 if(ret==st[i] || len==ret)//最重要的剪枝,如果找不到任意一个枝和当前的枝进行匹配,则说明不可能对了,就直接跳出大循环的! { break; } while(st[i]==st[i+1]){ //剪枝,第i根没有拼成的话,第i+1根和第i根长度相同的话也就拼不成了 i++; } } } return 0; } int main() { while(~scanf("%d",&n) && n!=0){ int i,sum=0,maxlen=0; for(i=0;i<n;i++){ scanf("%d",&st[i]); sum+=st[i]; if(st[i]>maxlen){ maxlen=st[i]; } } sort(st,st+n,cmp);//从大到小排 for(i=maxlen; i<=sum; i++) { if(sum%i==0){ memset(used,0,sizeof(used)); ans=dfs(i,0,i); if(ans!=0) break; } } printf("%d\n",ans); } return 0; }