世界冰球錦標賽 折半搜尋

2021-09-29 15:20:25 字數 3390 閱讀 1962

梁神園神

譯自 ceoi2015 day2 t1「ice hockey world championship」

今年的世界冰球錦標賽在捷克舉行。bobek 已經抵達布拉格,他不是任何團隊的粉絲,也沒有時間觀念。他只是單純的想去看幾場比賽。如果他有足夠的錢,他會去看所有的比賽。不幸的是,他的財產十分有限,他決定把所有財產都用來買門票。

給出 bobek 的預算和每場比賽的票價,試求:如果總票價不超過預算,他有多少種觀賽方案。如果存在以其中一種方案**某場比賽而另一種方案不**,則認為這兩種方案不同。

第一行,兩個正整數 n 和 m(1

≤n≤40

,1≤m

≤1018

)m(1 \leq n \leq 40,1 \leq m \leq 10^)

m(1≤n≤

40,1

≤m≤1

018)

,表示比賽的個數和 bobek 那家徒四壁的財產。

第二行,n 個以空格分隔的正整數,均不超過 1016

10^10

16,代表每場比賽門票的**。

輸出一行,表示方案的個數。由於 nn 十分大,注意:答案 ≤240

\le 2^

≤240

。5 1000

100 1500 500 500 1000

樣例解釋

八種方案分別是:

一場都不看,溜了溜了

**100的比賽

第一場**500的比賽

第二場**500的比賽

** 100 的比賽和第一場** 500的比賽

** 100 的比賽和第二場** 500的比賽

兩場** 500的比賽

** 1000 的比賽

有十組資料,每通過一組資料你可以獲得 10 分。各組資料的資料範圍如下表所示:

資料組號 1-21−2 3-43−4 5-75−7 8-108−10

n

≤n \leq

n≤10 | 20 | 40 |40

m ≤1

06∣1

018∣1

06∣1

018

m \leq10^6|10^ | 10^6|10^

m≤106∣

1018

∣106

∣101

8 這題在不是很相信洛谷上是紫題,畢竟很快就想出來了。

當然還是得益於大佬提點我的那句:爆搜。

機房有一大佬,一日與不知何處的小學弟qq上交流,學弟給出一題:現有一揹包,揹包有一承重w

n個物品,物品有重量v

iv_i

vi​,求裝揹包的方案數 。

n ≤40

,m≤1

018

n\leq40, m\leq10^

n≤40,m

≤101

8對,就是這道題改了下描述。

當日,大佬說題難度普及,要我與其同思其解,幫學弟解疑答惑。

我信了題目的鬼,深以為是揹包dp,思良久不得解。

忽另一大佬路過,聽其題意後,戲笑而說:爆搜

吾思之,n若為20,尚可列舉,今有40,不可列舉。

忽靈光一閃至,為何不從兩邊搜,一邊搜20,複雜度豈不可過

搜兩次,統計方法答案為何?

可若第二次搜完時列舉第一次狀態判斷合法否,複雜度仍為2

402^

240,吾休矣。

這時大佬突然對我施以援手:記錄第一次搜的狀態,排序,二分查詢

感激甚,大佬無愧於大佬,救人於水深火熱之中,如菩薩降臨,帶眾生脫離苦海。

好,第一次蒐時用a陣列存下合法狀態,即每次搜完後合法的門票價錢和。

對存下的狀態進行遞增排序

第二次時,對於每乙個搜完的合法狀態,我們記選擇的門票為b

bb;前一次搜出的狀態為a

ia_i

ai​那麼和並狀態時,合併合法的條件是ai+

b≤

ma_i + b \leq m

ai​+b≤

m 變一下就是ai≤

m−

ba_i \leq m - b

ai​≤m−

b我們剛剛對a陣列進行了排序,那麼我們就可以找到第乙個大於m−b

m-bm−

b的數,這個數前面的數都是合法的,

那麼合法的就有改數下標-1個,直接加到答案中去即可。

這樣的話我們的複雜度就是o(2

n2+2

n2lo

g(2n

2)

)o(2^} + 2^} log(2^}))

o(22n​

+22n

​log

(22n

​))此題可過矣。

c od

ecode

code

#include

#define ll long long

#define maxn 500010

#define n 201

#define inf 0x3f3f3f3f

#define gtc() getchar()

using

namespace std;

template

<

class

t>

inline

void

read

(t &s)

while

(isdigit

(ch)

) s *

= w;

}template

<

class

t>

inline

void

write

(t x)

int n;

ll m;

ll w[maxn]

;ll a[

1<<21]

, cnt =0;

int mid;

void

dfs(

int x, ll ans)

// printf("%d %d\n", x , ans);

dfs(x+

1, ans)

;dfs

(x+1

, ans + w[x]);

}ll ans =0;

void

dfs2

(int x, ll num)

dfs2

(x+1

, num)

;dfs2

(x+1

, num+w[x]);

}int

main()

世界冰球錦標賽題解

折半搜尋裸題 注意陣列大小要大於1048576,作者第一次提交就只開了1000000,鍋了 用乙個陣列c儲存並排序。在列舉後一半的方案,設其費用為w,按w從大到小排序,用乙個單調指標維護c陣列中小於等於m w的方案個數,ans累加方案個數。w從大到小,m w從小到大,指標單調右移 當然你也可以離散化...

洛谷P4799 世界冰球錦標賽 折半搜尋

給出n 40 n leq40 n 40 個比賽,給出每個比賽的票價以及m 1 e18 m leq1e18 m 1e18 表示你的積蓄。然後求問能看的比賽的方案數是多少。n nn如果能夠再小一些就可以直接暴搜了,但是搜不得。但是拆成兩半然後把兩邊所有的可行方案的總和全部儲存下來,對左邊的某個方案x x...

CEOI2015 Day2 世界冰球錦標賽

題目描述 譯自 ceoi2015 day2 t1 ice hockey world championship 今年的世界冰球錦標賽在捷克舉行。bobek 已經抵達布拉格,他不是任何團隊的粉絲,也沒有時間觀念。他只是單純的想去看幾場比賽。如果他有足夠的錢,他會去看所有的比賽。不幸的是,他的財產十分有限...