AcWing 146. 序列

原题链接

考察: 堆排序+归并排序

错误思路:

       枚举每一个可能的序列和,时间复杂度O(n*n^m),铁TLE

参考y总的思路:

      参考归并排序的思想,将选出m个元素的最小值之和换成先选出2个、3个、4个元素和的最小值,也就是说我们在M个序列里归并两个序列,选出这两个序列的n个最小和,再依次往下归并.如果暴力的话时间复杂度和上面相同,因此我们可以对a数组先排个序,将b数组与a数组合并,选出其中N个最小值赋值a数组,再合并后面的b数组

时间复杂度(n*(m-1)*logn)

 1 #include <iostream>
 2 #include <queue>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef pair<int,int> pii;
 7 const int N = 2010;
 8 int a[N],b[N],c[N],t,m,n;
 9 void merge()
10 {
11     priority_queue<pii,vector<pii>,greater<pii> >heap;
12     for(int i=1;i<=n;i++) heap.push({a[1]+b[i],1});//先初始化为a[1]+b[i]
13     int idx = 1;
14     while(idx<=n){
15         auto it = heap.top();
16         heap.pop();
17         int x = it.first; int y = it.second;
18         c[idx++] = x;
19         heap.push({x-a[y]+a[y+1],y+1});
20     }
21     for(int i=1;i<=n;i++) a[i] = c[i];
22 }
23 int main()
24 {
25     
26     scanf("%d",&t);
27     while(t--)
28     {
29         scanf("%d%d",&m,&n);
30         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
31         sort(a+1,a+n+1); m--;
32         while(m--)
33         {
34             for(int i=1;i<=n;i++) scanf("%d",&b[i]);
35             merge();
36         }
37         for(int i=1;i<=n;i++) printf("%d ",a[i]);
38         printf("\n");
39     }
40     return 0;
41 }

 

AcWing 146. 序列

上一篇:【OS_Windows】Windows主机之间远程拷贝文件


下一篇:Salesforce中调用REST API上传文件