考虑一个简单的问题,两个长度为n的有序数组A和B,从每个数组中各选出一个数相加,共n2中情况,求最小的n个数。

将这n2个数拆成n个有序表:

A1+B1≤A1+B2≤...

A2+B1≤A2+B2≤...

...

An+B1≤An+B2≤...

然后用优先队列合并成一个有序表即可。队列中需要记录两个数的和s,以及在B中的下标b,

比如Aa+Bb出队以后,应该将Aa+B(b+1) = Aa + Bb - Bb + Bb+1 = s - Bb + bb+1入队

对于书上最后的一个思考问题,merge函数中对A[0]又读又写,会不会出错。答案当然是不会的,因为进入到函数内部你会发现,对A数组其实是先读后写的。

 #include <cstdio>
#include <queue>
#include <algorithm>
using namespace std; const int maxn = + ;
int a[][maxn]; void scan(int& x)
{
char c;
while(c = getchar(), c < '' || c > '');
x = c - '';
while(c = getchar(), c >= '' && c <= '') x = x* + c - '';
} struct Node
{
int sum, b;
Node(int s, int b):sum(s), b(b) {}
bool operator < (const Node& rhs) const
{ return sum > rhs.sum; }
}; void merge(int n, int* A, int* B, int* C)
{
priority_queue<Node> Q;
for(int i = ; i < n; i++) Q.push(Node(A[i]+B[], )); for(int i = ; i < n; i++)
{
Node t = Q.top(); Q.pop();
int b = t.b, sum = t.sum;
C[i] = sum;
if(b + < n) Q.push(Node(sum-B[b]+B[b+], b+));
}
} int main()
{
//freopen("in.txt", "r", stdin); int k;
while(scanf("%d", &k) == )
{
for(int i = ; i < k; i++) scan(a[][i]);
sort(a[], a[] + k);
for(int i = ; i < k; i++)
{
for(int j = ; j < k; j++) scan(a[][j]);
sort(a[], a[] + k);
merge(k, a[], a[], a[]);
} for(int i = ; i < k; i++)
{
if(i) printf(" ");
printf("%d", a[][i]);
}
puts("");
} return ;
}

代码君

UVa 11997 (优先队列 多路归并) K Smallest Sums的更多相关文章

  1. UVa 11997 K Smallest Sums 优先队列&amp;&amp;打有序表&amp;&amp;归并

    UVA - 11997 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...

  2. 11997 - K Smallest Sums(优先队列)

    11997 - K Smallest Sums You’re given k arrays, each array has k integers. There are kk ways to pick ...

  3. D - K Smallest Sums(多路归并+贪心)

    Problem K K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pic ...

  4. 【暑假】[实用数据结构]UVa11997 K Smallest Sums

    UVa11997 K Smallest Sums  题目: K Smallest Sums You're given k arrays, each array has k integers. Ther ...

  5. UVA-11997 K Smallest Sums

    UVA - 11997 K Smallest Sums Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & ...

  6. uva 11997 优先队列

    K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pick exactly ...

  7. uva 11997 K Smallest Sums 优先队列处理多路归并问题

    题意:K个数组每组K个值,每次从一组中选一个,共K^k种,问前K个小的. 思路:优先队列处理多路归并,每个状态含有K个元素.详见刘汝佳算法指南. #include<iostream> #i ...

  8. UVA 11997 K Smallest Sums 优先队列 多路合并

    vjudge 上题目链接:UVA 11997 题意很简单,就是从 k 个数组(每个数组均包含 k 个正整数)中各取出一个整数相加(所以可以得到 kk 个结果),输出前 k 小的和. 这时训练指南上的一 ...

  9. UVA 11997 K Smallest Sums (多路归并)

    从包含k个整数的k个数组中各选一个求和,在所有的和中选最小的k个值. 思路是多路归并,对于两个长度为k的有序表按一定顺序选两个数字组成和,(B表已经有序)会形成n个有序表 A1+B1<=A1+B ...

随机推荐

  1. websphere变成英文了怎么变回中文

    今天进来发现,websphere在浏览器里面居然是英文的.这是因为我的浏览器少了一个中文语言设置,其实和页面编码无关. 解决办法: IE浏览器右键属性 -- internet选项 --  常规 -- ...

  2. RedHat Linux下注册Apache为系统服务并设为开机启动

    1.系统环境: 操作系统:Red Hat Enterprise Linux Server release 5.4 Apache版本:httpd-2.2.19 2.注册服务 #将apachectl复制到 ...

  3. 【WCF--初入江湖】03 配置服务

    03 配置服务 数据库 生成数据库脚本: CREATE DATABASE [EmployeeDb]; CREATE TABLE [dbo].[T_Employee]( [Id] [,) NOT NUL ...

  4. hdu 1754 线段树入门

    线段树点修改  区间最大值查询 #include <cstdio> #include <cstdlib> #include <cmath> #include < ...

  5. Unity3D WP8发布解决方案名 DefaultPackageName 修改问题

    原地址:http://blog.csdn.net/w337198302/article/details/16960661 在对Unity3D游戏进行Windows phone 8 发布的时候,首先是需 ...

  6. REST_FRAMEWORK加深记忆-极致抽象,极致完结

    余下的就是静心看官方文档了. 这个是最抽象的了. urls.py """tutorial URL Configuration The `urlpatterns` list ...

  7. hdu 4427 Math Magic DP

    思路: dp[i][j][k]表示满足前i个数,和为j,lcm为k的数目. 设a为解的第i+1个数. 那么状态转移就为 dp[i+1][j+a][lcm(a,k)]+=dp[i][j][k]. 但是由 ...

  8. 套题T3

    秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  9. URL中的特殊字符处理笔记

      URL中的特殊字符 有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了.编码的格式为:%加字符的ASCII码,即一个百分号%,后面跟对应字符的ASCII ...

  10. go学习资料及优秀博文

    相关书籍: Go Web编程 http://blog.csdn.net/broadview2006/article/details/8875097 优秀博文: 系统编程语言明日之星—Go(http:/ ...