(step4.3.10)hdu 1455(Sticks——DFS)

题目大意:

经典深搜   给你若干根短棒,将其组合成等长的木棒,尽可能短 ,并输出其长度


代码如下:

 

/*

 * 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);

	}

}



 

 

你可能感兴趣的:(HDU)