UVA 11997 The K smallest Sums

给出K*K的矩阵,每一行取一个数,构成K个数的和,总共有 k^k种可能,从中取出前k个最小的。

一开始犯了错,因为只要对每行排序,最小的必定是第一列的和,然后我当时就想着,逐步推进,每次将某行的那个数变成其下一列那个数,当然间距要最小。我这样明显是不对的,这样的话每个数只用了一次,而题目的意思明显是可以重复多次。

然后大白上说的是把他看成两行,即每次处理两行,留下最小的k个 再与下一次读入的那一行继续处理。这个方法相当给力,不过有个难点是,怎么在两行的时候,比较快的得到前k小的,我试过全部算一遍, k^k种情况。。会超时。。之后想了很久 都没想出一个比较有效的方法,后来看到一种很叼的方法,而且很容易证明,即 先把

排完序后的 第一行的 A【0】 到 A【K-1】 分别和 第二行的B【0】组成 最早的k个数,目前只知道A【0】+B【0】是最小的,其余的还不确定,但是我可以确定的是,第二小的,一定是A【0】+B【1】或者上述k-1个数中的某一个,也就是说,我把这些数,放入优先队列里面,然后每次pop出最小的数,输出,然后把刚刚最小的数的下一个又push进队列里面,则下一个pop出来的 必定是第二小的。。。这样的话 这样 重复k次,便能得到 前k小的数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
    int s,b;
    bool operator < (const node& rhs) const{
        return s>rhs.s;
    }
};
priority_queue<node> q;
const int N=800;
int n;
int A[N];
int B[N];
void solve()
{
    while (!q.empty()) q.pop();
    for (int i=0;i<n;i++){
        q.push((node){A[i]+B[0],0});
    }
    int cnt=0;
    while (cnt<n){
        node tmp=q.top();
        q.pop();
        A[cnt++]=tmp.s;
        q.push((node){tmp.s-B[tmp.b]+B[tmp.b+1],tmp.b+1});
    }

}
int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        while (!q.empty()) q.pop();
        for (int i=0;i<n;i++){
            scanf("%d",&A[i]);
        }
        for (int i=1;i<n;i++){
            for (int j=0;j<n;j++){
                scanf("%d",&B[j]);
            }
            sort(B,B+n);
            solve();
        }
        printf("%d",A[0]);
        for (int i=1;i<n;i++){
            printf(" %d",A[i]);
        }
        puts("");
    }
    return 0;
}

  

UVA 11997 The K smallest Sums

时间: 2025-01-04 03:40:55

UVA 11997 The K smallest Sums的相关文章

UVA 11997 【K Smallest Sums】

[题意分析] 本题目是要求总和最小的k个值,当然我们没有必要把所有的值全部求一次,我们首先应该对每组元素进行排序.然后根据两两合并的观点节约空间(先把前两组数据合并为一组数据,最后把下面的每一组数据和之前合并所得的那组数据进行合并).那么最后剩下的那组数据中的前k个数字就是最小的数字. [借鉴之处] 本题采用的两两合并的观点很新颖,值得学习理解. [AC代码] #include<iostream> #include<queue> #include<algorithm>

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

UVA - 11997 K Smallest Sums Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status You're given k arrays, each array has k integers. There are k^k ways to pick exactly one element in each array and calculate the sum o

【优先队列之多路合并】UVA - 11997 K Smallest Sums

Source : UVA - 11997 K Smallest Sums http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18702 题意 有k个整数数组,各包含k个元素,从每个数组中选取一个元素加起来,可以得到k^k个和,求这些和中最小的k个值. 示例 Sample Input 3 1 8 5 9 2 5 10 7 6 2 1 1 1 2 Sample Output 9 10 12 2 2 思路 二路归并构建二维平面表:

(DS 《算法竞赛入门经典》)UVA 11997 K Smallest Sums

题目大意:有k个数组,每个数组选取一个数,组成k^k个数.在这k^k个数中选择最小的前k个数 解题思路: 1.如果只有k个数组,那么最后得到的最小的前k个数应该可以由前两个数组得到的最小k个数与第三个数组 按规则运算后得到. 2.如果每个数组只有3个数.那么前两个数组(a:(a0,a1,a2)    b:(b0,b1,b2,a与b数组都已经有序)运算后有的结果矩阵如下: a0+b0,a0+b1,a0+b2 a1+b0,a1+b1,a1+b2 a2+b0,a2+b1,a2+b2 在这个矩阵中,a0

11997 - K Smallest Sums(优先队列)

11997 - K Smallest Sums You’re given k arrays, each array has k integers. There are kk ways to pick exactly one element in eacharray and calculate the sum of the integers. Your task is to find the k smallest sums among them.InputThere will be several

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

Problem K K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pick exactly one element in each array and calculate the sum of the integers. Your task is to find the k smallest sums among them. Input There will be se

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

UVa11997 K Smallest Sums  题目: K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pick exactly one element in each array and calculate the sum of the integers. Your task is to find the k smallest sums among them. In

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

vjudge 上题目链接:UVA 11997 题意很简单,就是从 k 个数组(每个数组均包含 k 个正整数)中各取出一个整数相加(所以可以得到 kk 个结果),输出前 k 小的和. 这时训练指南上的一道题,这道题的简化版其实在 15 年的广东省省赛出现过,当时是以送分题的形式出现的,可我还是没能做出来,归根到底还是看书不够,接触的题型不够多. *************************************************************大白书上的讲解开始*******

UVA 11997 K Smallest Sums 优先队列+归并 STL

题目链接: UVA...... 题目描述: 有K组数, 每组数有K个, 所以每组数各选一个加和有k^k种情况, 要求输出其中的最小的前k种, 从小到大输出 解题思路: 首先对于两个数组取前K个, 构造二元组(s, b) 其中s = Aa + Bb , a, b 为下标. 为什么不用三元组(s,a,b)呢, 因为二元组完全可以表示三元组, 下一个元素就是s+B[i+1]-B[i] . 我们需要把这k^2个和组织成如下k个有序表.(A, B是有序的哦) 表1:A1+B1<=A1+B2<=.....