1. 程式人生 > >【POJ 1011】 Sticks

【POJ 1011】 Sticks

names problem main esp str ++ sizeof pro clu

【題目鏈接】

http://poj.org/problem?id=1011

【算法】

深搜剪枝

首先我們枚舉木棍的長度i,那麽就有s/i根木棍,其中s為木棍長度的總和,樸素的做法就是對每種長度進行搜索,然而這樣是會超時的,考慮優化 :

優化1 : 優化搜索順序,將這些木棍的長度從大到小排序,搜索時按遞減的順序選取木棍(優先選擇長的木棍)

優化2 : 排除等效亢余,對於每根木棒,記錄最近一次嘗試的木棒,如果有與最近一次同樣長度的木棒,則不嘗試,因為這必定也是失敗的

優化3 : 排除等效亢余, 如果一根木棒嘗試的第一根木棍就失敗了,那麽直接返回失敗,因為其它木棒如果選這根木棍同樣是失敗的

【代碼】

#include <algorithm>  
#include <bitset>  
#include <cctype>  
#include <cerrno>  
#include <clocale>  
#include <cmath>  
#include <complex>  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <ctime>  
#include 
<deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include
<ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXN 110 int i,s,mx,n,cnt,tmp; int a[MAXN]; bool used[MAXN]; inline bool dfs(int dep,int now,int last) { int i,fail = 0; if (dep > cnt) return true; if (now == tmp) return dfs(dep+1,0,1); for (i = last; i <= n; i++) { if (!used[i] && now + a[i] <= tmp && fail != a[i]) { used[i] = true; if (dfs(dep,now+a[i],i+1)) return true; fail = a[i]; used[i] = false; if (!now) return false; } } return false; } int main() { while (scanf("%d",&n) && n) { s = 0; mx = 0; for (i = 1; i <= n; i++) { scanf("%d",&a[i]); s += a[i]; mx = max(mx,a[i]); } sort(a+1,a+n+1,greater<int>()); for (i = mx; i <= s; i++) { tmp = i; if (s % i) continue; cnt = s / i; memset(used,false,sizeof(used)); if (dfs(1,0,1)) break; } printf("%d\n",tmp); } return 0; }

【POJ 1011】 Sticks