洛谷P4799—— [CEOI2015 Day2]世界冰球錦標賽(折半搜尋)
原題連結
題意:
給n個物品和對應的價格,問用不超m元的錢可以買到的物品的方案數。
思路:
折半搜尋的入門題(霧.jpg)
n的範圍是n<=40。普通的搜尋一定會TLE,考慮將物品分成兩部分來搜尋,這樣時間複雜度就變成了2^(?/2+1);
基本思路就是對[1,mid] 和[mid+1],n兩個區間都進行dfs,分別記錄答案,再將兩個答案區間合併。
就本題而言,a陣列表示對[1,mid]進行搜尋,得到的方案;b陣列表示對[mid+1,n]進行搜尋,得到的方案。
區間合併時,對於a,b陣列裡的任意兩個數,只要和<=m都是合法的方案數,樸素解法是兩層for列舉,只能過40%的資料。優化是先將a陣列從小到大排序,再遍歷b陣列,在a陣列裡二分查詢b[i]+a[pos]<=m的最大的pos值,這樣pos之前的數一定也滿足該式。
程式碼:
注意陣列大小。
const int maxn=1e7+100;
ll n,m;
ll w[maxn],a[maxn],b[maxn];
ll cnta=0,cntb=0;
void dfs(ll l,ll r,ll sum,ll a[],ll &cnt){
if(sum>m) return ;///剪枝
if(l>r){
a[++cnt]=sum;return ;///搜尋完成
}
dfs(l+1,r,sum+w[l],a,cnt);///選當前數
dfs(l+1,r,sum,a,cnt);///不選當前數
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++) w[i]=read();
ll mid=n/2;///折半搜尋
dfs(1,mid,0,a,cnta);
dfs(mid+1,n,0,b,cntb);
sort(a+1,a+1+cnta);///對a陣列進行排序
ll res=0;
for(int i=1;i<=cntb;i++){
///遍歷b陣列 看b[i]和前面的幾個數的和不超過m
res+=upper_bound(a+1,a+1+cnta,m-b[i])-(a+1);
}
out(res);
return 0;
}
相關文章
- 折半搜尋學習筆記筆記
- 洛谷題單指南-搜尋-P1433 吃乳酪
- 二分搜尋(折半查詢)
- 洛谷題單指南-搜尋-P1162 填塗顏色
- 洛谷題單指南-搜尋-P2036 [COCI 2008/2009 #2] PERKET
- 洛谷 P5595 歌唱比賽
- 洛谷題單指南-搜尋-P1596 [USACO10OCT] Lake Counting S
- 花式極限摩托世界錦標賽中國站官方網站網站
- 洛谷題單指南-搜尋-P1019 [NOIP2000 提高組] 單詞接龍
- 洛谷
- 牛客練習賽 37 C 筱瑪的迷陣探險 【折半搜尋+01字典樹】
- 洛谷11月月賽題解(A-C)
- 洛谷-P1036-選數(順便講講深搜)
- 洛谷團隊
- 二分搜尋之搜尋陣列中目標元素的首尾下標陣列
- 洛谷死亡時間
- 洛谷P1786
- 洛谷 - P5369
- 洛谷P6786
- 洛谷P10725
- 洛谷P10693
- 洛谷 - P6190
- 洛谷——玩具謎題
- 英雄聯盟(洛谷)
- 洛谷 P6464 [傳智杯 #2 決賽] 傳送門
- 織夢標籤搜尋框呼叫
- 易優searchform功能:文件標題搜尋,預設搜尋整站-EyouCms手冊ORM
- 第三屆電競上海全民錦標賽總決賽即將開賽!
- 洛谷網校學習
- 昨天放洛谷的圖
- 將洛谷私信接入WindowsWindows
- 洛谷 P10254 口吃
- 洛谷傻逼之處
- 洛谷八皇后問題
- 洛谷 P3958乳酪
- 【洛谷】【分支】月份天數
- 洛谷P1291 [SHOI2002]百事世界盃之旅(期望DP)
- 洛谷P8208 [THUPC2022 初賽] 骰子旅行 題解 期望DP