UVA 11997 【K Smallest Sums】

【题意分析】

本题目是要求总和最小的k个值,当然我们没有必要把所有的值全部求一次,我们首先应该对每组元素进行排序。然后根据两两合并的观点节约空间(先把前两组数据合并为一组数据,最后把下面的每一组数据和之前合并所得的那组数据进行合并)。那么最后剩下的那组数据中的前k个数字就是最小的数字。

【借鉴之处】

本题采用的两两合并的观点很新颖,值得学习理解。

【AC代码】

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
struct  Item
{
  int s,b;
  Item(int s,int b):s(s),b(b){}
  bool operator <(const Item &a) const{
      return s>a.s;
  }
} ;
void merge(int *A,int *B,int *C,int n)
{
    priority_queue<Item>q;
    for(int i=0;i<n;i++)
    q.push(Item(A[i]+B[0],0));
    for(int i=0;i<n;i++)
    {
     Item item =q.top();q.pop();
     int b=item.b;
     C[i]=item.s;
     if(b+1<n)  q.push(Item(item.s-B[b]+B[b+1],b+1));//细细体会此处 
    }
}
const int maxn=768;
int A[maxn][maxn];
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            scanf("%d",&A[i][j]);
            sort(A[i],A[i]+n);
        }
        for(int i=1;i<n;i++)
        {
            merge(A[0],A[i],A[0],n);
        }
        printf("%d",A[0][0]]);
        for(int i=1;i<n;i++)
        printf(" %d",A[0][i]);
        printf("\n");    
    }
    return 0;
}

 

posted @ 2014-09-06 16:02  future_hero  阅读(208)  评论(0编辑  收藏  举报