ZZ的橱柜
Description:
ZZ不仅喜欢买衣服,还是个吃货,天哪!现在的妹纸是怎么了?╮(╯_╰)╭,ZZ有两个大型橱柜A和B,里面放满了零食,每个橱柜里面有N个方格,每个方格里面放了不同重量的美味,现在ZZ要从A、B里面各取一个方格的美味,可是ZZ不想变得太胖,于是他会尽量的选择重量少的美味,当然不是所有的组合都是ZZ喜欢吃的美味,所以她想了一个特别的方法,他会选出组合重量最小的前M种中选出一种,可是怎么才能算出前M个组合的重量的呢?这个真是个难题,作为ACMer的ZZ竟然不能解决,你能帮帮她么?
Input:
有多组测试数据;
第一行给你一个N(N<=400000)和一个M(M<=N),N表示每个壁橱有N个方格,M表示要选出M中方案;
第二行和第三行分别有N个整数,表示每个方格的美味重量(结果保证在int以内)
Output:
输出前M种方案的重量,每种方案占一行
Sample:
测试输入: |
测试输出: |
2 2 1 2 3 4 |
4 5
|
1 /* 队列实现多路归并问题:将多个有序表按条件合并成一个有序表, 2 N为归并次数 && 改变重载运算符可以改变归并后表的顺序 */ 3 #include <queue> 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #define N 200 8 using namespace std; 9 int a[N][N]; 10 struct node 11 { 12 int s,c; 13 // s为和 c为下标 14 }; 15 bool operator<(node a , node b) 16 { 17 return a.s<b.s; 18 } 19 int cmp(int x , int y) {return x>y;} 20 void merge(int *a , int *b , int *c , int k) 21 { 22 int i , j; 23 priority_queue<node> que; 24 for(i=0 ; i<k ; i++) 25 que.push((node){a[i]+b[0],0}); 26 for(i=0 ; i<k ; i++) 27 { 28 node q = que.top(); que.pop(); // a[0]+b[0] 29 c[i] = q.s; 30 int nt = q.c; 31 if(nt+1<k) que.push((node){q.s-b[nt]+b[nt+1],nt+1}); 32 // s=a[0]+b[0] -> s'=a[0]+b[1]=a[0]+b[0]-b[0]+b[1]=s-b[0]+b[1]; 33 } 34 } 35 /* 实现从大到小排序 */ 36 int main () 37 { 38 int i , j , k; 39 while(cin>>k,k) 40 { 41 for(i=0 ; i<k ; i++) 42 { 43 for(j=0 ; j<k ; j++) 44 cin>>a[i][j]; 45 sort(a[i],a[i]+k,cmp); 46 } 47 for(i=1 ; i<k ; i++) 48 merge(a[0] , a[i] , a[0] , k); 49 for(i=0 ; i<k ; i++) 50 cout<<a[0][i]<<' '; 51 cout<<endl; 52 } 53 return 0; 54 }