zoukankan      html  css  js  c++  java
  • UVA 11997 STL 优先队列

    题目链接:

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3148

    题意:给K个数组,每个数组含有K个整数,从每个数组中各选一个数加起来,得到一个sum,这样的选法一共有K^k种,现在求这样的和中最小的K个sum.

    解法:先考虑两个数组的情形

    假设A1<=A2<=`````<=AK

    B1<=B2<=`````<=Bk

    则有

    A1+B1<=A1+B2<=`````<=A1+Bk.

    A2+B1<=A2+B2<=`````<=A2+Bk.

    ```````

    Ak+B1<=Ak+B2<=`````<=Ak+Bk.

    首先把第一列的数<s[i] = A[i] + B[1]     ,      1>,第一个数为和,第二个数为B的序号,放入优先队列,然后从优先队列中弹出最小的,这个最小值一定是所有和中最小的,同时压入A[a] + B[b+1],A[a]+B[b+1] = s-B[b]+B[b+1]....这样循环n次即可。得到了n个最小和。因为这里有k个数组,两两合并即可。

    以上摘自刘汝佳的大白书190页。(是看了他的书写的,如果有错了不是他写错了,必然是我写错了)

    贴代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<queue>
     4 using namespace std;
     5 #define N 755
     6 int k[N][N],n;
     7 struct Item
     8 {
     9     int s,b;//s = A[a] + B[b]
    10     Item(int s,int b):s(s),b(b) {}
    11     bool operator<(const Item & other)const
    12     {
    13         return s > other.s;
    14     }
    15 };
    16 void output(int a[])
    17 {
    18     printf("array :
    ");
    19     for(int i=0; i<n; ++i)
    20         printf("%d ",a[i]);
    21     puts("");
    22 }
    23 void combine(int A[],int B[])
    24 {
    25     priority_queue<Item> q;
    26     for(int i =0; i<n; ++i)
    27         q.push(Item(A[i]+B[0] , 0));
    28     for(int i=0; i<n; ++i)
    29     {
    30         Item item = q.top();
    31         q.pop();
    32         A[i] = item.s;
    33         int b = item.b;
    34         if(b+1 < n ) q.push(Item(item.s - B[b] + B[b+1] , b+1));
    35     }
    36 }
    37 int main()
    38 {
    39 //    freopen("in.txt","r",stdin);
    40     while(~scanf("%d",&n))
    41     {
    42         for(int i=0; i<n; ++i)
    43         {
    44             for(int j=0; j<n; ++j)
    45                 scanf("%d",&k[i][j]);
    46             sort(k[i],k[i]+n);
    47         }
    48         for(int i=1; i<n; ++i)
    49             combine(k[0],k[i]);
    50         printf("%d",k[0][0]);
    51         for(int i=1; i < n; ++i)
    52             printf(" %d",k[0][i]);
    53         puts("");
    54     }
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    导入测试用例的设计
    质量管理的精髓
    ios crash的原因与抓取crash日志的方法
    怎样实现excel隔行隔列变色效果的方法
    如何提高员工的质量意识?
    史上最全的测试团队组建方法
    如何写好缺陷报告?
    你还不知道?这四个因素决定了你的养老金待遇!
    各手机截屏方法收集
    利用drozer进行Android渗透测试
  • 原文地址:https://www.cnblogs.com/allh123/p/3287425.html
Copyright © 2011-2022 走看看