题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2460

网上很多题目都没说这个题目的证明,只说了贪心策略,我比较愚钝,在大神眼里的显然的策略还是想证明一下才安心……所以这里记录一下证明过程。

贪心策略:按魔力值从大到小排序,从大往小往线性基里插,如果成功插入新元素,就选这个,如果插不进去,就不选这个。

证明:

  设有n个材料,每个材料的属性值是x[1],x[2],...,x[n],魔力值是v[1],v[2],...,v[n],这里假设v已经排好序,即v[1]>=v[2]>=v[3]>=...>=v[n]。

  首先证,一定有一个最优解,包含材料1,其属性值是x[1],魔力值是v[1]。

    假设原问题存在一个最优解 S = { t1, t2, ... , tk }。其中ti代表第ti个物品,且t1<t2<...<tk。

      如果t1等于1,那么得证。

      如果t1不等于1,那么我们来证一定有一个元素可以被1替换下来。

        考虑1为何不能加进S。因为S是线性无关的,加入1以后,S∪{1}就变得线性相关了。所以必然存在S的一个子集,它们的异或和等于x[1]。

        用表达式写出来也就是

(1)

        那么1可以把谁替换下来呢?答案是1可以把任何一个替换下来。我们不妨让它替换下来ti,把式子变一下形,两边同时异或上x[ti]^x[1],就得到了

(2)

        就会发现x[ti]已经可以被线性表示出来了,而且显然,如果不加x[1]肯定是无法线性表示出来x[ti]的(因为S是线性无关的),所以替换后的线性基跟原来是等价的。

        如果不放心,我可以再重述一遍,对于原来S可以表示出来的,替换后的一定也可以表示出来,因为被替换掉的x[ti]已经可以表示出来了;对于原来S不能表示出来的,替换后的也一定表示不出来。可以用反证法证。假设有一个y,用原来的表示不出来,而用替换后的可以表示出来。那肯定是因为加入了x[1]的原因。用式子写出来就是:

(3)

        把x[1]用(1)式代换,就可以得到:

(4)

        是不是担心,万一左边的x都抵消没了怎么办?实际上不会出现这种情况,因为ti就是独一无二的,在x[i]^...^x[j]里是不会有的(因为ti已经被1替换下来了)。这样,就得到了原来的基也可以得到y,与假设矛盾。

  所以这一步证明的作用是什么呢?就是证明了,第一步的贪心策略是正确的。下面来证明,如果第一步的贪心是正确的,以后的贪心也是正确的。

  现在只需证,假设当前已经按照贪心策略造出了一个线性无关的基S = { t1, t2, ... , tk },一定存在一个最优解,包含下一步选择的那个最大魔力值的跟S线性无关的一个材料。

  设下一步的贪心策略选择是j,假设最优解是 G = {t1, t2, ... , tk , tk+1, tk+2, ... , tk+m}。

    如果j∈G,那么得证。

    如果j∉G,现在证j一定可以替换掉G中的某个元素,实际上j可以替换掉跟它线性相关的那些元素里的任何一个元素,证明方法跟第一步类似。

      j为什么不能属于G呢?因为G是线性无关的,但是加入j之后,就线性相关了,也就是说j是多余的,j可以用其他的线性表示出来。那么可以得到的式子就是:

(5)

(补充:图片里的i, j, k都是代指任意变量)

    这个式子实际上跟(1)式是一模一样的。而且这里的i肯定>k,因为根据已知的策略,j一定会选跟t1...tk线性无关的最前面的那个。那么到此,后面的证明跟第1步的证明也是类似的,j也可以替换掉任何一个ti (i>k)。

  综上,问题得证。

代码:

#include<bits/stdc++.h>
using namespace std; typedef long long ll; const int maxn=;
pair<int,ll> a[maxn]; vector<ll> base;
bool add(ll x)
{
for(int i=;i<base.size();i++)
x=min(x,x^base[i]);
if (x) base.push_back(x);
if (x) return true;
else return false;
} int main()
{
int n;
scanf("%d",&n);
for (int i=;i<n;i++) scanf("%lld%d",&a[i].second,&a[i].first);
sort(a,a+n);
int ans=;
for (int i=n-;i>=;i--) if (add(a[i].second)) ans+=a[i].first;
printf("%d",ans);
return ;
}

[bzoj 2460]线性基+贪心+证明过程的更多相关文章

  1. bzoj 2460 线性基

    #include<bits/stdc++.h> #define ll long long #define LL long long #define int long long using ...

  2. BZOJ 2460 & 洛谷 P4570 [BJWC2011]元素 (线性基 贪心)

    题目链接: 洛谷 BZOJ 题意 给定 \(n\) 个矿石,每个矿石有编号和魔力值两种属性,选择一些矿石,使得魔力值最大且编号的异或和不为 0. 思路 线性基 贪心 根据矿石的魔力值从大到小排序. 线 ...

  3. bzoj 3105: [cqoi2013]新Nim游戏【线性基+贪心】

    nim游戏的先手必胜条件是所有堆的火柴个数异或和为0,也就是找一个剩下火柴堆数没有异或和为0的子集的方案,且这个方案保证剩下的火柴个数总和最大 然后我就不会了,其实我到现在也不知道拟阵是个什么玩意-- ...

  4. BZOJ 2460: [BeiJing2011]元素 贪心,线性基

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2460 解法:从大到小排序,依次贪心的添加到当前集合就可以了,需要动态维护线性基.用拟阵证明 ...

  5. BZOJ.2460.[BeiJing2011]元素(线性基 贪心)

    题目链接 线性基:https://blog.csdn.net/qq_36056315/article/details/79819714. \(Description\) 求一组矿石,满足其下标异或和不 ...

  6. bzoj 2460: [BeiJing2011]元素【线性基+贪心】

    先按魔力值从大到小排序,然后从大到小插入线性基中,如果插入成功就加上这个魔力值 因为线性基里是没有异或和为0的集合的,所以正确性显然,然后最优性,考虑放进去一个原来没选的,这样为了可行性就要删掉一个, ...

  7. bzoj 2115 Xor - 线性基 - 贪心

    题目传送门 这是个通往vjudge的虫洞 这是个通往bzoj的虫洞 题目大意 问点$1$到点$n$的最大异或路径. 因为重复走一条边后,它的贡献会被消去.所以这条路径中有贡献的边可以看成是一条$1$到 ...

  8. BZOJ.3105.[CQOI2013]新Nim游戏(线性基 贪心 博弈论)

    题目链接 如果后手想要胜利,那么在后手第一次取完石子后 可以使石子数异或和为0.那所有数异或和为0的线性基长啥样呢,不知道.. 往前想,后手可以取走某些石子使得剩下石子异或和为0,那不就是存在异或和为 ...

  9. BZOJ 4269: 再见Xor 线性基+贪心

    Description 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. Input 第一行一个正整数N. 接下来一行N个非负整数. ...

随机推荐

  1. 1014C程序语法树

    程序:冒泡算法C程序 #include <stdio.h> main() { int i,j,temp; int a[10]; for(i=0;i<10;i++) scanf (&q ...

  2. Navicat Premium_11.2.7简体中文版 破解版本 windows版本

    亲测可用 自己一直在用的 https://pan.baidu.com/s/1VVKKQoIKVB0BgNXBK4YTrQ

  3. 【uoj#180】[UR #12]实验室外的攻防战 结论题+树状数组

    题目描述 给出两个长度为 $n$ 的排列 $A$ 和 $B$ ,如果 $A_i>A_{i+1}$ 则可以交换 $A_i$ 和 $A_{i+1}$ .问是否能将 $A$ 交换成 $B$ . 输入 ...

  4. 转:SVM与SVR支持向量机原理学习与思考(一)

    SVM与SVR支持向量机原理学习与思考(一) 转:http://tonysh-thu.blogspot.com/2009/07/svmsvr.html 弱弱的看了看老掉牙的支持向量机(Support ...

  5. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

  6. MyBatis之自查询,使用 递归实现 N级联动

    A:首先先看下一个简单的面试题 斐波那契数列 计算数组{1,1,2,3,5,8.......} 第30位值 规律:1 1 从第三项开始,每一项都是前两项之和 有两种实现方式 第一种方式: public ...

  7. 嘘,如何激活更新的win10

    win10更新了,所以很坑的是以前的密钥又不管用了,系统和office都要重新激活,然而微软的更新就是很有恶意的,总之成功率堪忧. 还好看到了万能的网友的办法. slmgr.vbs /upk slmg ...

  8. python 常用 time, datetime处理

    python 中 time 有三种格式: float, struct tuple(time.struct_time 或 datetime.datetime), str 常用的: float --> ...

  9. jetBrains 插件开发第一课-- 在主菜单栏新增一个菜单

    环境搭建完了,接下来可以开始写代码了: 1.新建 plugin 项目 2.编辑 plugin.xml,修改一下里面的插件名那些信息,该文件的配置项可以看这里:plugin.xml 其中比较关键的有一个 ...

  10. laravel 5.5 在构造函数使用Session

    public function __construct() { $this->request = request(); // 验证是否登录 $this->middleware(functi ...