P4570 [BJWC2011]元素

【题意】

给定n个矿石,有价值和编号,求一个选择的矿石集合,使其中不存在一个子集的异或和为0,求这个集合的价值最大

【分析】

我们可以贪心的考虑, 如果当前存在x^y^z=0,那么意味着我们肯定要舍去一个,一定会舍去价值最小的那个

所以我们可以按照价值排序,加入线性基,直到无法加入为止

【代码】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1005;
int n;
ll a[maxn],p[maxn],ans;
struct point
{
    ll num,val;
}e[maxn];
bool cmp(point a,point b)
{
    return a.val>b.val;
}
int main()
{
//    freopen("a.in","r",stdin);
//    freopen("a.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld%lld",&e[i].num,&e[i].val); 
    sort(e+1,e+n+1,cmp);
    for(int i=1;i<=n;i++)
        for(int j=63;j>=0;j--)
        {
            if(!(e[i].num&(1LL<<j))) continue;
            if(p[j]) e[i].num^=p[j];
            else
            {
                p[j]=e[i].num;
                ans+=e[i].val;
                break;
            }
        }
    printf("%lld",ans);
    return 0;
}

 

posted @ 2021-05-29 10:52  andyc_03  阅读(43)  评论(0编辑  收藏  举报