1. 程式人生 > >hdu 1455 sticks(經典深搜+剪枝技巧)

hdu 1455 sticks(經典深搜+剪枝技巧)



題意:有一堆的木棒,長度不一,它們是有一些整齊的木棒截斷而成的,求最小的木棒原始長度。

思路很簡單深搜,但是直接深搜的話會tle,首先可以對木棒長度進行排序從大到小,優先使用長度長的木棒,加入當前長度不符合,考慮下一個木棒

其次如果長度為零的時候選擇木棒失敗,那麼直接退出,實測加上這一剪枝就可以ac,這一剪枝可以幫助我們儘可能的在靠近樹根處剪枝,所以優化效果很明顯。

然後是如果這次選擇的木棒長度和上次失敗時的一樣,那麼剪枝。

#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<cstdlib>  
#include<iostream>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<queue>  
#include<stack> 
#include<string>
#include<map> 
#include<set>
#define eps 1e-6 
#define LL long long  
using namespace std;  

const int maxn = 70;
const int INF = 0x3f3f3f3f;
int n, sumv, target, aim;//target表示目標的棍子個數,aim表示目標的棍子長度 
int stick[maxn], vis[maxn];
bool cmp(int a, int b) {
	return a > b;
}

void init() {
	sumv = 0;
	for(int i = 0; i < n; i++) {
		cin >> stick[i]; sumv += stick[i];
	}
	sort(stick, stick+n, cmp);
}

bool dfs(int cnt, int len, int pos) {
	if(cnt == target) return true;
	if(len == aim) return dfs(cnt+1, 0, 0); 
	for(int i = pos; i < n; i++) {                         //從大到小排序後,按順序搜尋 
		if(!vis[i] && len+stick[i] <= aim) {
			vis[i] = 1;
			if(dfs(cnt, len+stick[i], i+1)) return true;
			vis[i] = 0;                                     
			if(len == 0) return false;                     //如果第一根時失敗剪枝 
			while(i+1 < n && stick[i+1] == stick[i]) i++;  //如果下一根長度跟當前的失敗的長度一樣,剪枝 
		}
	}
	return false;
}

void solve() {
	int ans = 0;
	for(int i = 1; i <= sumv; i++) if(sumv % i == 0) {
		memset(vis, 0, sizeof(vis));
		aim = i; target = sumv / aim;
		if(dfs(0, 0, 0)) {
			ans = aim; break;
		}
	}
	cout << ans << endl;
}

int main() {
//	freopen("input.txt", "r", stdin);
	while(scanf("%d", &n) == 1 && n) {
		init();
		solve();
	}
	return 0;
}










相關推薦

hdu 1455 sticks經典+剪枝技巧

 題意:有一堆的木棒,長度不一,它們是有一些整齊的木棒截斷而成的,求最小的木棒原始長度。 思路很簡單深搜,但是直接深搜的話會tle,首先可以對木棒長度進行排序從大到小,優先使用長度長的木棒,加入當

POJ-1011-Sticks dfs+剪枝

原題連結: http://poj.org/problem?id=1011 George took sticks of the same length and cut them randomly until all parts became at most 50 units long. N

HDU 1455 SticksDFS,剪枝,原來木棒的至少長度

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

HDU-1016 Prime Ring ProblemDFS+打表

inf rap problem pac 如果 pos using 所有 get 題目回顧(HDU-1016): Prime Ring Problem Problem Description A ring is compose of n circles as shown

HDU 1455 Sticks分組

題目: 把陣列分成一些組,使得每個組的和都是r,求r的最小值 Description George took sticks of the same length and cut them randomly until all parts became at most

HDU 1455——Sticks神棍

這題跟 HDU1518差不多 附上測試資料~~ 64 40 40 30 35 35 26 15 40 40 40 40 40 40 40 40 40 40 40 40 40 40  40 40 43 42 42 41 10 4 40 40 40 40 40 40 40

poj(1011)——Sticks經典的dfs+剪枝

題目的大致意思是: 現在有n根木棍,然後需要把它們拼成同樣長度的木棍,問滿足這個條件的最短的長度是多少? 想法嘛:那肯定是dfs把長度搜一遍就好,但問題的關鍵是這裡會超時。那麼就要用到剪枝的原理了。 以下部分是來自於pku的gw老師說噠 1)不要在同一個位置多次嘗試相同長度

hdu 1455 sticks【dfs】+經典剪枝

ems clas .net tdi pac target 構建 algorithm stream 題目鏈接:https://vjudge.net/problem/HDU-1455 轉載於:>>>>>> 題目大意: George把一些等長的

hdu 1416Gizilchdfs

Problem Description The game of gizilch has very simple rules. First 100 grapes are labeled, in nontoxic ink, with the numbers 1 to

hdu1518Square+剪枝

Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square? Input The first

poj 1011 hdoj 1455 Sticks搜尋+剪枝

題目連結 大致題意: 有n跟棍, 求它們能組成最短且長度相同的棍的長度 解題思路: DFS+剪枝 POJ2362的強化版,重點在於剪枝   建議你先看看這道題  here 令initlen為所求的最短原始棒長,maxlen為給定的棒子堆中最長的棒子,su

HDU1455 Sticks(+剪枝)

題意:有一堆的木棒,長度不一,它們是有一些整齊的木棒截斷而成的,求最小的木棒原始長度。 思路很簡單深搜,但是直接深搜的話會tle,首先可以對木棒長度進行排序從大到小,優先使用長度長的木棒,加入

HDU 4616 Game經典樹形dp+最大權值和鏈

using bsp mes size hdu pen typedef style 最大的 http://acm.hdu.edu.cn/showproblem.php?pid=4616 題意:給出一棵樹,每個頂點有權值,還有存在陷阱,現在從任意一個頂點出發,並且每個頂點只能

+剪枝--poj2676--數獨

數字 元素 但是 blank back .org round 數據 設置 題幹描述 就是一個數獨問題 這道題說是剪枝,但是我覺得主要還是好在gw老師的設置的數據結構太好了。見代碼。 當要在一個空格子(0)放數字時,直接放那些在這個空格子所在行、列、3*3小方框沒出現過的

HDU多校9 Rikka with Nash Equilibrium記憶化索/dp

align previous msu higher ali mem import eno ont Rikka with Nash Equilibrium Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 52

P1220 關路燈 動態規劃/剪枝

        題目描述 某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小(即同一段時間內消耗的電量有多有少)。老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。 為了給村裡節省電費,老張

兩點51nod

福克斯在玩一款手機解迷遊戲,這個遊戲叫做”兩點”。基礎級別的時候是在一個n×m單元上玩的。像這樣: 每一個單元有包含一個有色點。我們將用不同的大寫字母來表示不同的顏色。 這個遊戲的關鍵是要找出一個包含同一顏色的環。看上圖中4個藍點,形成了一個環。一般的,我們將一個序列 d1,d

HDU5952 Counting Cliques (暴力+剪枝) (2016ACM/ICPC亞洲賽區瀋陽站 Problem E)

題目連結:傳送門 題目: Counting Cliques Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 4879

POJ-1724 剪枝

這道題目如果資料很小的話。我們通過這個dfs就可以完成深搜: void dfs(int s) { if (s==N) { minLen=min(minLen,totalLen); return ; } for (int i=0;i<G[s].size();i++) {

HDU-Wooden Sticks貪心

Wooden Sticks There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a wood