zoukankan      html  css  js  c++  java
  • POJ2442

    题目:http://poj.org/problem?id=2442

    题意:给m个包含n个数字的数列,在每个数列中选一个数加起来,这样的和由nm个,求这些和中最小的前n个。

    可以先看两个数列的情况,假设这两个数列为A,B。先将这两个数列从小到大排序,那么最小的和肯定是A[1]+B[1],而第二小的就是min(A[2]+B[1],A[1]+B[2]),假设就是A[2]+B[1]吧。那么第三小的就是min(A[2]+B[1],A[3]+B[1],A[1]+B[2]),根据这个规律,我们知道,如果确定A[i]+B[j]是前n个中的一个那么就可以将A[i]+B[j+1]和A[i+1]+B[j]纳入下一个最小值的考虑范围之内。那么我们用优先队列就可以动态的取我们考虑范围内的最小值,从而得出这两个数列前n小和。

    如果扩展到m个数列的话,我们可以先求出前2个数列的前n小和,然后利用这个结果和第3个数列,求出前3个数列的前n小和,以此类推,求出m个数列的前n小和。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #define MAXN 2010
    using namespace std;
    int T,n,m,num1[MAXN],num2[MAXN],num3[MAXN],vis[MAXN][MAXN];
    struct Node{
        int i,j;
        
        friend bool operator < (const Node &a,const Node &b)
        {
            return num1[a.i]+num2[a.j]>num1[b.i]+num2[b.j];
        }
    };
    priority_queue<Node> pq;
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d %d",&m,&n);
            for(int i=1;i<=n;i++) scanf("%d",&num3[i]);
            sort(num3+1,num3+n+1);
            for(int i=2;i<=m;i++)
            {
                memset(vis,0,sizeof(vis));
                for(int j=1;j<=n;j++) scanf("%d",&num2[j]);
                sort(num2+1,num2+n+1);
                for(int j=1;j<=n;j++) num1[j]=num3[j];
                while(!pq.empty()) pq.pop();
                pq.push({1,1});
                for(int j=1;j<=n;j++)
                {
                    int p1=pq.top().i,p2=pq.top().j;
                    pq.pop();
                    num3[j]=num1[p1]+num2[p2];
                    if(p1<n&&!vis[p1+1][p2]) pq.push({p1+1,p2}),vis[p1+1][p2]=1;
                    if(p2<n&&!vis[p1][p2+1]) pq.push({p1,p2+1}),vis[p1][p2+1]=1;
                }
            }
            for(int i=1;i<=n;i++) printf("%d ",num3[i]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    JS调用App方法及App调用JS方法
    提升用户体验之 选用合适的鼠标光标
    js仿QQ拖拽删除
    Linux下安装 mongodb
    QQ分享-定制分享卡片
    js判断浏览器语言实现网站国际化
    js复制内容到剪切板
    为什么会有堆内存和栈内存之分
    Avro实现RPC
    zookeeper学习day01
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11317022.html
Copyright © 2011-2022 走看看