折半搜索

折半搜索

假设每一位都要k种情况,则直接搜索的复杂度为\(O(N\)k\()\),折半搜索复杂度为\(O(2*N\)k/2\()\)

#include<bits/stdc++.h>
#define N 44
#define int long long
using namespace std;

int n,m,a[N],p1[1<<22],cnt1,ans;

void dfs1(int now,int st,int ed)
{
	if(now>m) return;
	p1[++cnt1]=now;
	if(st>ed) return;
	for(int i=st;i<=ed;++i) dfs1(now+a[i],i+1,ed);
}

void dfs2(int now,int st,int ed)
{
	ans+=upper_bound(p1+1,p1+cnt1+1,m-now)-p1-1;
	
	if(st>ed) return;
	
	for(int i=st;i<=ed;++i) dfs2(now+a[i],i+1,ed);
}

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;++i) scanf("%lld",a+i);
	
	int mid=n>>1;
	dfs1(0,1,mid);
	
	sort(p1+1,p1+cnt1+1);
	
	dfs2(0,mid+1,n);
	cout<<ans;
	return 0;
}
posted @ 2020-10-23 19:39  林生。  阅读(109)  评论(0)    收藏  举报