柵欄的木料(二分 dfs)

2021-07-08 14:56:55 字數 1811 閱讀 4532

題目描述 

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,再後面的搜尋的下界就會大大...