題目描述
description
農民john準備建乙個柵欄來圍住他的牧場。他已經確定了柵欄的形狀,但是他在木料方面有些問題。當地的雜貨儲存商扔給john一些木板,而john必須從這些木板中找出盡可能多所需的木料。
當然,john可以切木板。因此,乙個9英呎的木板可以切成乙個5英呎和乙個4英呎的木料 (當然也能切成3個3英呎的,等等)。john有一把(完美的)夢之鋸,因此他在切木料時,不會有木料的損失。
所需要的柵欄長度可能會有重複(比如,乙個3英呎和另乙個3英呎長的柵欄可能同時都需要)。所需要的木料規格都已經給定。你不必切出更多木料,那沒有用。
輸入描述
input description
第1行: n (1 <= n <= 50), 表示提供的木板的數目
第2行到第n+1行: n行,每行包括乙個整數,表示各個木板的長度。
第n+2行: r (1 <= r <= 1023), 所需木料的數目
第n+3行到第n+r+1行: r行,每行包括乙個整數(1 <= ri <= 128)表示所需木料的長度。
輸出描述
output description
只有一行,乙個數字,表示能切出的最多的所需木料的數目。當然,並不是任何時候都能切出所有所需木料。
樣例輸入
sample input 4
3040
5025
1015
1617
1819
2021
252430
樣例輸出
sample output 7
#include#include#include#includeusing namespace std;
int len[53],ans[1024],lentot,n,m,sum[1024],i,j,ok,wanow,wamax,tt,head,tail,mid;
int cmp(int a,int b)
void dfs(int k,int last)//k表示當前該截那一段了,從需求長的開始截
{
int i,where;
if (ans[k]==ans[k+1])//對於相同長度的需求可從上一層的位置向下搜尋,減小搜尋範圍
where=last;
else
where=1;
for (i=where;i<=n;++i)//木板長度從大到小開始搜尋
if (len[i]>=ans[k])//可以截出當前需求
{ len[i]-=ans[k];
if (len[i]1&&wanow<=wamax)
dfs(k-1,i);
if (len[i]ans[head+1])//保證一塊木板能截出一段所需木料的長度,計算至少能滿足多少需求
head++;
else
break;
tail=m;
while (sum[tail]>lentot)//所需木料總長超過木板的總長,捨去最長的需求
tail--;
while (ans[tail]>len[1])//最長的所需木料超過最長的木板的長度,無法滿足捨去
tail--;
while (tail>head)//二分尋找能滿足的所需木料數量
{
mid=(head+tail+1)>>1;
wanow=0;
for (i=n;i>=1;i--)
if (len[i]
柵欄 二分 dfs 貪心
農夫約翰打算建立乙個柵欄將他的牧場給圍起來,因此他需要一些特定規格的木材。於是農夫約翰到木材店購 買木材。可是木材店老闆說他這裡只剩下少部分大規格的木板了。不過約翰可以購買這些木板,然後切割成他所需 要的規格。而且約翰有一把神奇的鋸子,用它來鋸木板,不會產生任何損失,也就是說長度為10的木板可以切成...
bzoj 1082 柵欄(二分 DFS)
傳送門biu 先排序,二分最多能得到多少木板,顯然要盡量選小的木板,當木材大小小於最小的木塊時丟棄。記錄當前丟棄的木材量,若加上mid塊木板 所有的木材 則不合法。includeusing namespace std int m,n,mid bool flag int a 55 sa,b 1005 ...
USACO 4 1 2 柵欄的木料
這個講的超好.一定要看.然後看我 就好懂啦.各種優化確實非常好.搜尋的一道好題.掛 problem usaco 4.1.2 柵欄的木料 author robert yuan 優化解釋 0.二分 貪心判斷可行解 根據自己設計的貪心演算法盡量的得到乙個比較靠近正確值的 ans,再後面的搜尋的下界就會大大...