BJWC 2011 元素 题解

本文探讨了一道算法题目,利用线性基的概念解决了一个关于元素选择与最大魔力值的问题。通过深入分析线性基的第三条性质,解释了为何贪心策略在此类问题中总是能得到最优解。并提供了C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目传送门

题目大意: n n n 个东西,每个东西能选当且仅当它的元素序号不能通过之前选过的东西的元素序号异或得到,在此前提下,求魔力的最大值。

题解

如果没看过我写的关于线性基的博客,请先阅读一下吧,特别是理解其中的第三条性质。

根据这条性质,我们可以知道,一个序列,能够插入到线性基里面的元素是一定的,那么既然只能插那么多个,显然优先插魔力值大的进去呀!

可能有人会问,如果有三个数 a , b , c ( a < b < c ) a,b,c(a<b<c) a,b,c(a<b<c),先插入 c c c导致 a a a b b b都不能插入,但是 a + b > c a+b>c a+b>c,如果先将 a , b a,b a,b插入到线性基里面,那么得到的值的和不是更大吗?

是会更大,但是这种情况不存在。(没想到吧)

仔细想想,假如插入了 c c c 之后会导致 a , b a,b a,b 不能插入,那么插入了 a a a b b b 后也肯定会导致另外两个不能插入。

所以,按这种贪心的做法得到的一定是最优的,不可能因为一个元素而导致多个元素不能插入,就算去掉这个元素,也只能插入那多个元素中的一个。

代码就很简单了:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long

struct node{ll x;int y;};
node a[1010];
int n,ans=0;
ll d[70];
bool cmp(node x,node y){return x.y>y.y;}
bool add(ll x)
{
    for(int i=62;i>=0;i--)
    {
        if(x&(1ll<<i))
        {
            if(!d[i])
            {
                d[i]=x;
                return true;
            }
            else x^=d[i];
        }
    }
    return false;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%lld %d",&a[i].x,&a[i].y);
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    if(add(a[i].x))ans+=a[i].y;
    printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值