题目大意:
经典深搜 给你若干根短棒,将其组合成等长的木棒,尽可能短 ,并输出其长度
代码如下:
/*
* 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\n",len);
}
}