梁神園神
譯自 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 已經抵達布拉格,他不是任何團隊的粉絲,也沒有時間觀念。他只是單純的想去看幾場比賽。如果他有足夠的錢,他會去看所有的比賽。不幸的是,他的財產十分有限...