(hdu step 4.3.5)Sticks(将n根木棒合成若干根等长的木棒,求合成后的木棒的长度的最小值)

题目:

Sticks

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 364 Accepted Submission(s): 116
 

Problem Description

George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.


Input

The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.


Output

The output file contains the smallest possible length of original sticks, one per line.


Sample Input

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0


Sample Output

6
5

 

Source

ACM暑期集训队练习赛(七)


Recommend

lcy

题目分析:

DFS。

代码如下:

/*
 * e.cpp
 *
 *  Created on: 2015年2月25日
 *      Author: Administrator
 */

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 65;

bool visited[maxn];//用于标记某个木棒是否已经使用过
int values[maxn];//结果序列
bool flag;//用于标记使用已经成功找到一种方案
int parts;//标记木棒的份数
int len;//等长木棒的长度
int n;//原始木棒序列的根数

/**
 * 深搜。
 * pos:当前搜索的的木棒的索引
 * cur:当前已经拼成的木棒的长度
 * cnt:当前已经拼好的木棒的数量
 */
void dfs(int pos,int cur,int cnt){

	if(cur == len){//如果当前木棒的长度==指定的木棒长度
		cnt++;//拼好的木棒的数量+1

		if(cnt == parts){//如果拼好的木棒数量==指定的木棒数量
			flag = true;//将flag标记为true,表示已经成功
			return ;//返回
		}
		//如果还没有拼够指定数量的等长木棒
		dfs(0,0,cnt);//则继续拼
	}

	if(pos >= n){//如果当前搜索到的木棒的索引已经超出了木棒的范围
		return ;//则返回,表示没有成功
	}

	int i;
	for(i = pos ; i < n ; ++i){//从当前木棒开始向后扫
		if(visited[i] == false  && values[i] + cur <= len){//如果该根木棒没有被访问过&&当前木棒的长度+已经拼好的木棒的长度<=len
			visited[i] = true;//则将该木棒标记为已经访问过
			dfs(i+1,values[i]+cur,cnt);//在此基础上继续往下搜
			visited[i] = false;//回滚

			/**
			 * 剪枝。
			 * 如果当前已经找到一种方案,则返回
			 * pos的那个剪枝我也还没有想明白,没加的时候TLE.
			 *
			 */
			if(flag == true|| pos == 0){
				return ;
			}

		}
	}
}

int main(){
	while(scanf("%d",&n)!=EOF,n){
		int maxLen = -1;
		int sum = 0;

		int i;
		for(i = 0 ; i < n ; ++i){
			scanf("%d",&values[i]);

			if(values[i] > maxLen){
				maxLen = values[i];//计算所有木棒中的最大长度
			}
			sum += values[i];//计算所有木棒的总长度
		}

		/**
		 * 从单根木棒的最大长度开始枚举所有情况。
		 * 为什么从但根木棒的最大值开始枚举而不是从最小值开始枚举呢?因为最小值的情况下,
		 * 比最小值长度要大的木棒必然会被废弃.这很明显不符合题意
		 */
		for(len = maxLen ; len < sum ; ++len){
			if(sum%len == 0){//如果该长度下,木棒能够被等分
				memset(visited,false,sizeof(visited));
				parts = sum/len;//计算该长度下能分成多少根木棒
				flag = false;//重新将flag设置成false
				dfs(0,0,0);//开始搜索

				if(flag == true){//如果已经成功
					break;//跳出循环
				}
			}
		}

		printf("%d\n",len);//输出找到的合成后的木棒的最小的长度
	}

	return 0;
}
时间: 2024-10-12 23:23:07

(hdu step 4.3.5)Sticks(将n根木棒合成若干根等长的木棒,求合成后的木棒的长度的最小值)的相关文章

(hdu step 6.1.7)Connect the Cities(在有的路已经修建好的情况下,求让n个点连通的最小费用)

题目: Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 391 Accepted Submission(s): 139   Problem Description In 2100, since the sea level rise, most of the cities disappear. Though

(hdu step 5.1.4)Farm Irrigation(在两个节点合并有限制条件的情况下,求集合的个数)

题目: Farm Irrigation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 202 Accepted Submission(s): 104   Problem Description Benny has a spacious farm land to irrigate. The farm land is a rectangle,

hdu 5203 Rikka with wood sticks

题意: 勇太有一根长度为n的木棍,这个木棍是由n个长度为1的小木棍拼接而成,当然由于时间放置的久了,一些小木棍已经不牢固了,所以勇太想让六花把这个木棍分成正整数长度的4段,其中有3段要没有不牢固的小木棍,勇太希望这3段木棍的长度和可以最大.同时六花希望在满足勇太要求的情况下让这三根木棍能拼成一个三角形,请问萌萌哒六花有多少种可行的分割方案呢? 限制: 1 <= n <= 1e6; 1 <= m <= 1e3 思路: 实际上问题会化为: 1. 给出长度为l1,l2的木棒,把其中一根截

(hdu step 1.3.8)Who&#39;s in the Middle(排序)

题目: Who's in the Middle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2938 Accepted Submission(s): 1109   Problem Description FJ is surveying his herd to find the most average cow. He wants to k

(hdu step 1.3.1)FatMouse&#39; Trade(在收入需要一定的付出的情况下求最大收入)

题目: FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5092 Accepted Submission(s): 1530   Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats gua

(hdu step 6.1.2)Eddy&#39;s picture(在只给出二维坐标点的情况下,求让n个点连通的最小费用)

题目: Eddy's picture Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 172 Accepted Submission(s): 126   Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to be

(hdu step 5.1.1)A Bug&#39;s Life((ai,bi)表示ai、bi不在同一堆中,有若干对数据,判断是否有bug)

题目: A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 723 Accepted Submission(s): 277   Problem Description Background Professor Hopper is researching the sexual behavior of a rare spe

(hdu step 3.2.4)FatMouse&#39;s Speed(在第一关键字升序的情况下,根据第二关键字来求最长下降子序列)

在写题解之前给自己打一下广告哈~..抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下: http://edu.csdn.net/course/detail/209 题目: FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1034 Accepted Submission(s): 526   Proble

(hdu step 3.1.5)Tiling_easy version(求用2*1、2*2两种骨格铺满2*n的网格的方案数)

在写题解之前给自己打一下广告哈~..抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下: http://edu.csdn.net/course/detail/209 题目: Tiling_easy version Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 515 Accepted Submission(s): 447   Prob