在使用搜尋的時候,當n過大2n會超時,這時候可以用折半搜尋,把時間複雜度降低到2n/2+1題目鏈結具體方法:分別搜尋前一半,把狀態放入a陣列,搜尋後一半,把狀態放入b陣列,最後統計答案。
一般meet in the middle的難點主要在於最後答案的組合統計。
我們可以現將a或b陣列sort,讓其有序。然後通過列舉另乙個陣列中的狀態,來實現統計答案。
題意:給定n(<=40)場比賽門票各自的**,和bobek擁有的錢數,求觀賽方案總數。(如果存在以其中一種方案**某場比賽而另一種方案不**,則認為這兩種方案不同。可以一場也不看)
思路:240的搜尋肯定會超時,所以折半搜尋。
#include
using namespace std;
#define ll long long
const
int maxn=
1<<21;
ll m,ans,a[50]
,suma[maxn]
,sumb[maxn]
;int n,cnta,cntb;
void
dfs(
int t,
int m,ll f[
],ll s,
int&cnt)
dfs(t+
1,m,f,s,cnt)
;dfs
(t+1
,m,f,s+a[t]
,cnt);}
intmain()
cout<
}
題目鏈結
題意:給n(<=20)個數,從中任意選出一些數,使這些數能分成和相等的兩組。求有多少種選數的方案。
思路:這道題有三種狀態:①不放入任何集合 ②放入左邊集合 ③放入右邊集合[面向題解設計程式。。一知半解]
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
int n,mid;
struct nodesuma[
1<<22]
,sumb[
1<<22]
;int cnta,cntb,m[44]
,r;bool vis[
1<<23]
;ll ans;
void
dfs(
int l,
int flag,
int sum,
int t)
else
return;}
dfs(l+
1,flag,sum,t)
;dfs
(l+1
,flag+(1
<<
(l-1))
,sum+m[l]
,t);
dfs(l+
1,flag+(1
<<
(l-1))
,sum-m[l]
,t);
}inline bool cmp1
(node x,node y)
inline bool cmp2
(node x,node y)
intmain()
r++;}
if(l
.v==suma[l+1]
.v)r=p;
l++;}
cout<
}
poj 折半搜尋
題意 給你乙個含有n n 1000 個數的數列,問這個數列中是否存在四個不同的數a,b,c,d,使a b c d 若存在則輸出最大的d 思路 完全暴力的話o n 4 會t,可以考慮雙向搜尋,公式變形為a b d c 分別列舉a b和c d,將值和下標存在結構體中,再二分查詢即可 include in...
折半搜尋 某種密碼
某種密碼 描述關於某種密碼有如下描述 某種密碼的原文a是由n個數字組成,而密文b是乙個長度為n的01數串,原文和密文的關聯在於乙個鑰匙碼key。若key ai bi key ai bi 則密文就是原文的一組合法密碼。現在有原文和鑰匙碼,請編乙個程式來幫助他統計到底有多少個符合條件的密文。輸入第一行兩...
折半列舉(雙向搜尋)
各有n個整數的四個數列a b c d。要從每個數列中各取乙個數,使四個數的和為0。求出這樣組合的個數。輸入n 6 a b c d 從4個數列中選擇共有n4種情況,全部判斷一遍不可行。不過將它們對半分成ab和cd再考慮,就可以快速解決了。從2個數列中選擇的話只有n2種組合,所以可以進行列舉。先從a b...