清北学堂 清北-Day5-R2-xor

\(n\) 个物品,每个物品有两个属性 \(a_i,b_i\) ,挑选出若干物品,使得这些物品 \(a_i\) 的异或和 \(x \le m\).问在这一限制下,\(b_i\) 的总和最大可能为多少.
输入
输入文件名为xor.in。
第一行两个数 \(n,m (n \le 32)\)
接下来n行每行两个数 \(a_i\)\(b_i\)
输出
输出文件名为xor.out。
一个数表示答案
样例输入

4 5
1 2
2 1
3 3
4 1

样例输出

7

提示
【数据说明】
对于30%的数据,$1 \le n \le 20,1 \le a_i , m<2^{30} $

对于另外30%的数据,$1 \le n \le 32,1 \le a_i , m < 2^{18} $

对于100%的数据,\(1 \le n \le 32,1 \le a_i , m < 2^{30},b[i] \le 10^6\)

本来我又以为是个神仙DP.....比如什么EX背包啊啥的
但是转眼一看数据范围—— \(meet \: in \: the \: middle\)
但是我不想写,于是就写了一个彻彻底底的爆搜!
然后....然后就A了,爆搜也没什么好讲的,直接上代码吧:

#include <algorithm> 
#include <iostream>
#include <cstdlib>
#include <cstdio>
#define ll long long
#define max(a,b) (a>b?a:b)

const ll N = 40;

struct things{ll weight,value;}t[N];

ll ans,sum[N],n,m;

inline bool cmp(const things&a,const things&b){return a.value > b.value;}

inline void dfs(ll wet,ll val,ll step){
	if(wet <= m) ans = max(ans,val);
	if(step >= n + 1) return ;
	if(sum[step] + val <= ans) return ;
	dfs(wet ^ t[step].weight , val + t[step].value , step + 1);
	dfs(wet , val , step + 1);
	return ;
}

int main(){
	scanf("%lld%lld",&n,&m);
	for(int i = 1 ; i <= n ; ++ i) scanf("%lld%lld",&t[i].weight,&t[i].value);
	std::sort(t + 1 , t + n + 1 , cmp);
	for(int i = n ; i >= 1 ; -- i) sum[i] = sum[i + 1] + t[i].value;
	dfs(0,0,1);printf("%lld\n",ans);
	return 0;
}
posted @ 2018-11-01 20:50  Phecda  阅读(230)  评论(1编辑  收藏  举报

Contact with me