zoukankan      html  css  js  c++  java
  • UVA11997 K Smallest Sums(优先队列)

    刘汝佳新书---训练指南

    题意:有K个整数数组,包含K个元素。在每个数组中取一个元素加起来,可以得到k^k个和。求这些和中最小的K个值

    分析:这题有简化版本的,即2个整数数组A,B,包含K个元素,在每个数组中取一个元素加起来,可以得到k^2个和,求这些和中最小的K个值。

    我们需要把这k^2个和组织成如下k个有序表.

    表1:A1+B1<=A1+B2<=......<=A1+Bk

    表2: A2+B1<=A2+B2<=......<=A2+Bk

    表k:Ak+B1<=AK+B2<=......<=Ak+Bk

    我们可以用二元组(s,b)来表示一个元素即s=Aa+Bb;为什么不保存A的下标a呢?因为我们用不到a的值。如果我们需要元素(s,b)在表a的下一个元素(s',b+1).只需要计算s'=s+B[b+1]-B[b];

    这样我们先将K个表的第一个元素压入优先队列,这样队列中就用k个元素了。然后从队列中出一个值,就压入这个值所在表的下一个元素,直到k个值都出了优先队列。这样就得到k个最小值了。。

    然后对与K个数组。我们只需两两合并即可。

    // File Name: 11997.cpp
    // Author: zlbing
    // Created Time: 2013/3/8 20:19:01
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,n) for(int i=0;i<n;i++)
    #define REP1(i,n) for(int i=1;i<n+1;i++)
    #define MAXN 1000
    int G[MAXN][MAXN];
    int k;
    struct Item{
        int s,b;
        bool operator <(const Item& r)const{
            return s>r.s;
        }
    };
    void merge(int *A,int *B,int *C){
        int cnt=0;
        priority_queue<Item> Q;
        for(int i=0;i<k;i++)Q.push((Item){A[i]+B[0],0});
        while(!Q.empty()){
            Item t=Q.top();
            Q.pop();
            C[cnt++]=t.s;
            if(t.b+1<k)Q.push((Item){t.s+(B[t.b+1]-B[t.b]),t.b+1});
            if(cnt==k)break;
        }
        //for(int i=0;i<k;i++)printf("%d ",C[i]);
    }
    int main(){
        while(~scanf("%d",&k))
        {
            REP(i,k){
                REP(j,k)
                    scanf("%d",&G[i][j]);
                sort(G[i],G[i]+k);
            }
            REP1(i,k-1)merge(G[0],G[i],G[0]);
            REP(i,k)
                if(i==0)printf("%d",G[0][i]);
                else printf(" %d",G[0][i]);
            printf("\n");
        }
        return 0;
    }
  • 相关阅读:
    Android中Tomcat的简单配置和使用
    Android Toast 总结(五种用法)
    软件工程—软件开发生命周期
    Android四大组件之BroadcastReceiver
    Android之 Fragment
    Android 四大组件之Acticity
    java 注解Annotation
    Android Intent的使用
    Android 调用webService(.net平台)
    关于TouchEvent中出现异常:MessageQueue-JNI问题
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2950772.html
Copyright © 2011-2022 走看看