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

本文介绍了一种使用爆搜策略解决特定约束条件下,寻找具有最大b_i总和的物品组合的方法。问题背景涉及从n个具有a_i和b_i属性的物品中选择若干个,使所选物品的a_i异或和不超过m,同时b_i总和最大。通过分析数据范围和采用排序、深度优先搜索等技巧,实现了高效求解。

有 $ 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;
}

转载于:https://www.cnblogs.com/Equinox-Flower/p/9892406.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值