清北学堂 清北-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
",ans);
	return 0;
}
May you return with a young heart after years of fighting.
原文地址:https://www.cnblogs.com/Equinox-Flower/p/9892406.html