ZZ的橱柜

Description

ZZ不仅喜欢买衣服,还是个吃货,天哪!现在的妹纸是怎么了?╮(_)╭,ZZ有两个大型橱柜AB,里面放满了零食,每个橱柜里面有N个方格,每个方格里面放了不同重量的美味,现在ZZ要从AB里面各取一个方格的美味,可是ZZ不想变得太胖,于是他会尽量的选择重量少的美味,当然不是所有的组合都是ZZ喜欢吃的美味,所以她想了一个特别的方法,他会选出组合重量最小的前M种中选出一种,可是怎么才能算出前M个组合的重量的呢?这个真是个难题,作为ACMerZZ竟然不能解决,你能帮帮她么?

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 }
View Code(归并)

 

posted @ 2013-05-21 23:00  1002liu  阅读(145)  评论(0编辑  收藏  举报