K优解

Time Limit: 20 Sec  Memory Limit: 512 MB

Description

  给定n个行数,每行m个。在每行中选出一个数来,求出前 k 小的异或和。

Input

  第一行 3 个正整数 n,m,k。
  接下来 n 行,每行 m 个非负整数,第 i 行第 j 个为权值a[i][j]。

Output

  一行一个数表示答案。

Sample Input

  3 2 2
  11 21
  9 25
  17 19

Sample Output

  2

HINT

  n*m<=300000,k<=300000,保证m^n>=k,a[i][j]均不超过10^9

Solution

  先对于每个 i,将每行的 a[i][1]~a[i][m] 从小到大排序,再将按照其元素差值多关键字排序(共m-1个关键字)。

  那么我们知道,最小的方案肯定是所有行都取第一个。由于其有一些特殊,我们先抛开这个方案。
  我们知道,次小的方案是(2,1,1,1…),把这个状态加入堆,由较优方案扩展较劣方案,对于每一个状态,我们记录其扩展到第几行,以及取第几个元素

  在已经得到前 k 优的方案时,当前所有方案中还未扩展的最好的方案x(其最后扩展位置为 i),就是第 k+1 优

  从方案x,我们可以扩展出几个较劣解

    1、x 的第 i 个元素不取m:将 i 行取的元素增加1(扩展位置为 i

    2、i + 1 <= n:将 i+1 行取为2(扩展位置为 i+1

    3、x 的第 i 个元素取为2i + 1 <= n:将 i 行取为1,i+1 行取为2(扩展位置为 i+1

  由此,每个解都可由唯一的优于它的解扩展得来。

  用个维护一下,每次取出最小的即可。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9 + ; int n, m, k;
vector <int> A[ONE];
int id[ONE];
s64 Ans; struct power
{
s64 val;
int pt, id;
bool operator <(power a) const
{
return a.val < val;
}
};
priority_queue <power> q; int cmp(int a, int b)
{
for(int i = ; i < m; i++)
{
if(A[a][i + ] - A[a][i] < A[b][i + ] - A[b][i]) return ;
if(A[a][i + ] - A[a][i] > A[b][i + ] - A[b][i]) return ;
}
return ;
} int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int main()
{
n = get(); m = get(); k = get();
for(int i = ; i <= n; i++)
{
A[i].push_back();
for(int j = ; j <= m; j++)
A[i].push_back(get());
sort(A[i].begin(), A[i].end());
id[i] = i;
} sort(id + , id + n + , cmp); s64 res = ;
for(int i = ; i <= n; i++) res += A[i][];
Ans = res; q.push((power){res - A[id[]][] + A[id[]][], , }); for(int i = ; i <= k; i++)
{
power u = q.top(); q.pop();
Ans ^= u.val; if(u.id + <= m)
q.push((power){u.val - A[id[u.pt]][u.id] + A[id[u.pt]][u.id + ], u.pt, u.id + });
if(u.pt + <= n && <= m)
q.push((power){u.val - A[id[u.pt + ]][] + A[id[u.pt + ]][], u.pt + , });
if(u.pt + <= n && u.id == )
q.push((power){u.val - A[id[u.pt]][] + A[id[u.pt]][] - A[id[u.pt + ]][] + A[id[u.pt + ]][], u.pt + , });
} printf("%lld", Ans);
}

【Foreign】K优解 [堆]的更多相关文章

  1. hdu 2639 Bone Collector II (01背包,求第k优解)

    这题和典型的01背包求最优解不同,是要求第k优解,所以,最直观的想法就是在01背包的基础上再增加一维表示第k大时的价值.具体思路见下面的参考链接,说的很详细 参考连接:http://laiba2004 ...

  2. HDU 2639 (01背包第k优解)

    /* 01背包第k优解问题 f[i][j][k] 前i个物品体积为j的第k优解 对于每次的ij状态 记下之前的两种状态 i-1 j-w[i] (选i) i-1 j (不选i) 分别k个 然后归并排序并 ...

  3. 01背包之求第K优解——Bone Collector II

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 题目大意是,往背包里赛骨头,求第K优解,在普通01背包的基础上,增加一维空间,那么F[i,v,k]可以理解 ...

  4. hdu2639(背包求第k优解)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:给出一行价值,一行体积,让你在v体积的范围内找出第k大的值 分析:dp[i][j][k]表 ...

  5. 关于01背包求第k优解

    引用:http://szy961124.blog.163.com/blog/static/132346674201092775320970/ 求次优解.第K优解 对于求次优解.第K优解类的问题,如果相 ...

  6. (01背包 第k优解) Bone Collector II(hdu 2639)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639       Problem Description The title of this problem i ...

  7. 背包的第k优解[动态规划]

    From easthong ☆背包的第k优解                 描述 Description     DD 和好朋友们要去爬山啦!他们一共有 K 个人,每个人都会背一个包.这些包的容量是 ...

  8. dp之01背包hdu2639(第k优解)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:给出一行价值,一行体积,让你在v体积的范围内找出第k大的值.......(注意,不要 和它的第一题混 ...

  9. Bone Collector II---hdu2639(01背包求第k优解)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639求01背包的第k大解.合并两个有序序列 选取物品i,或不选.最终的结果,是我们能在O(1)的时间内 ...

随机推荐

  1. 20172333 2017-2018-2 《Java程序设计》第10周学习总结

    20172333 2017-2018-2 <Java程序设计>第10周学习总结 教材学习内容 第十三章 集合是一个对象,一个保存其他对象的数据库. 集合可以保存不同种类的对象也可以保存同种 ...

  2. a2

    Alpha 冲刺报告 队名: 组长:吴晓晖 今天完成了哪些任务: 代码量300+,完成了百度地图API的引入. 展示GitHub当日代码/文档签入记录: 明日计划: 整理下这两个功能,然后补些bug ...

  3. lintcode-176-图中两个点之间的路线

    176-图中两个点之间的路线 给出一张有向图,设计一个算法判断两个点 s 与 t 之间是否存在路线. 样例 如下图: for s = B and t = E, return true for s = ...

  4. caffe2安装教程

    相比于网上的安装教程不如直接看官方安装教程:https://caffe2.ai/docs/getting-started.html?platform=windows&configuration ...

  5. ZOJ 1403 F-Safecracker

    https://vjudge.net/contest/67836#problem/F "The item is locked in a Klein safe behind a paintin ...

  6. 【Docker 命令】 - search 命令

    docker search : 从Docker Hub查找镜像 语法 docker search [OPTIONS] TERM OPTIONS说明: --automated :只列出 automate ...

  7. 第71天:jQuery基本选择器(二)

    jQuery选择器 一.内容过滤选择器 选择器 描 述 返 回 示 例 :contains(text) 匹配含有文本内容text的元素 集合元素 $(“p:contains(今天)”) :empty ...

  8. 【bzoj1692】[Usaco2007 Dec]队列变换 贪心+后缀数组

    题目描述 FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”.在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席前依次走过. ...

  9. 关于 [lambda x: x*i for i in range(4)] 理解

    题目: lst = [lambda x: x*i for i in range(4)] res = [m(2) for m in lst] print res 实际输出:[6, 6, 6, 6] 想要 ...

  10. 【倍增】LCM QUERY

    给一个序列,每次给一个长度l,问长度为l的区间中lcm最小的. 题解:因为ai<60,所以以某个点为左端点的区间的lcm只有最多60种的情况,而且相同的lcm区间的连续的. 所以就想到一个n*6 ...