题目大意:
经典深搜 给你若干根短棒,将其组合成等长的木棒,尽可能短 ,并输出其长度
代码如下:
/* * 1455_3.cpp * * Created on: 2013年8月23日 * Author: Administrator */ #include <iostream> using namespace std; /** * kp[] :用来记录被剪后每根木棒的长度 * mark[] :用来标记是否访问过 * n : 被剪后木棒的根数 * sum :木棒的总长度 * flag : 用来标记是否成功 * len : 组合后木棒的长度 * parts :组合后木棒的根数 */ int kp[65]; bool mark[65]; int n; int sum; bool flag; int len; int parts; int maxn ; bool compare(const int& a , const int& b){ return a > b; } /** * pos :当前搜索到的位置 * cur :当前的木棒长度 * cnt :当前的木棒根数 */ void dfs(int pos, int cur , int cnt){ //如果成功 if(flag){ return ; } //如果当前的木棒长度==组合后的木棒长度 if(cur == len){ cnt++; //如果当前的木棒根数==组合后的木棒根数 if(cnt == parts){ flag = true; } //从剩下的棍子中继续选取相加长度为len的组合 dfs(0,0,cnt); return ; } //如果当前搜索到的位置 == 被剪后的木棒根数 if(pos == n){ return ; } int pre = -1; int i; for( i = pos ; i < n ; ++i){ //如果该木棒没有被访问过&&该木棒的长度!=前面木棒的长度&&当前的木棒姆安巴那个长度+该木棒长度<=len if(!mark[i] && kp[i] != pre && kp[i] + cur <= len){ pre = kp[i]; mark[i] = true; dfs(i+1,kp[i] + cur , cnt); mark[i] = false; if(flag || pos ==0){ //如果已经有解或者选取第一个尚未被选取的元素时取不到len的长度,则剪枝 return ; } } } } int main(){ while(scanf("%d",&n)!=EOF,n){ int i; sum = 0; maxn = -INT_MAX;//INT_MAX :2147483647 for( i = 0 ; i < n ; ++i){ scanf("%d",&kp[i]); if (kp[i] > maxn) {//*** maxn = kp[i]; } sum += kp[i]; } sort(kp,kp+n,compare); for(len = maxn ; len < sum ; ++len){ if(sum % len ==0){ memset(mark,0,sizeof(mark)); flag = 0; parts = sum / len; dfs(0,0,0); if(flag){ break; } } } printf("%d ",len); } }