双向搜索模板

https://ac.nowcoder.com/acm/contest/889/D

降低指数级数据的复杂度(本题从2^36降至2^18)

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

ll num[40];
set<ll> st;
map<ll,ll> mp; 
int main()
{
	ll n,s;
	cin>>n>>s;
	
	int mid=n/2;//二分搜索 把数量级从10次方降到6次方 
	int right=n-mid;
	for(int i=0;i<n;i++){
		scanf("%lld",&num[i]);
	}
	
	//前半段 
	for(int i=0;i<(1<<mid);i++){//二进制序列 
		ll res=0;
		for(int j=0;j<mid;j++){
			if(i&(1<<j))res+=num[j];//把二进制序列中为1的位累加起来 也就是枚举前半段所有的情况 
		}
		st.insert(res);
		mp[res]=i;//st与mp配套 
	}
	
	for(int i=0;i<(1<<right);i++){
		ll res=0;
		for(int j=0;j<right;j++){
			if(i&(1<<j))res+=num[j+mid];
		}
		
		if(st.find(s-res)!=st.end()){
			for(int j=0;j<mid;j++)if(mp[s-res]&(1<<j))putchar('1');else putchar('0');
			for(int j=0;j<right;j++)if(i&(1<<j))putchar('1');else putchar('0');
			puts("");
			return 0;		
		}
	}
	
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值