首页 > 其他 > 详细

2017 ECJTU ACM 程序设计竞赛

时间:2017-11-21 23:07:32      阅读:356      评论:0      收藏:0      [点我收藏+]

大厦

Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 25   Accepted Submission(s) : 7

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

给你一个n(1<=n<=1000)层楼的大厦,每一楼里面有m(1<=m<=1000)房间,
每个房间一定的金钱X(1<=x<=1000),假设不同楼层的房间是互通的,相同楼层的房间是不互通的。也就是说每层只能取一个,现在给你一个捡钱的机会。捡钱的方式不同,会导致你得到的钱的不同,求可能捡到的钱的前k大的和

Input

输入一个T,表示T组样例;
每组数据第一行输入n,m,k
接下来输入n行,每行m个数,代表这个房间拥有的金钱

Output

输出可能捡到的钱的前k大的和

Sample Input

1
3 4 5
1 2 3 4
5 6 7 8
1 2 3 4

Sample Output

75


题解

假设任意两层为集合A B(从大到小排序)对于B集合的元素B[i],显然它和A[1]组合值最大,
如果B[i]+A[j]是前K大值中的一个,那么B[i]+A[k](1<=k < j)必然也是前K大的,
所以B[i]+A[j]被选则B[i]+A[j-1]之前就被选了,
所以优先队列中只需维护Size(B)个元素,首先把A[1]+B[i]全部进队,
每次从队首拿出一个组合(i,j)(表示A[i]+B[j]),把A[i+1]+B[j]进队,
直到拿出K个元素为止,即为这两个集合合并的前K大
n层的话只要把每次得到的结果和其他层按照这样处理就可以了


AC代码
 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <iostream>
 6 #include <sstream>
 7 #include <algorithm>
 8 #include <string>
 9 #include <queue>
10 #include <vector>
11 using namespace std;
12 const int maxn= 1005;
13 const double eps= 1e-6;
14 const int inf = 0x3f3f3f3f;
15 typedef long long ll;
16 int k,n,m;
17 vector<int> a[maxn];
18 vector<int> ans,d;
19 int cmp(int a,int b)
20 {
21     return a>b;
22 }
23 struct node
24 {
25     int i,j,val;
26     node(){}
27     node(int i,int j,int val):i(i),j(j),val(val){}
28     bool operator <(const node &a)const
29     {
30         return val<a.val;
31     }
32 };
33 int main()
34 {
35     int t;
36     scanf("%d",&t);
37     while(t--)
38     {
39         scanf("%d %d %d",&n,&m,&k);
40         int x;
41         for(int i=1;i<=n;i++)
42             a[i].clear();
43         ans.clear();
44         for(int i=1;i<=n;i++)
45         {
46             for(int j=1;j<=m;j++)
47             {
48                 scanf("%d",&x);
49                 a[i].push_back(x);
50             }
51             sort(a[i].begin(),a[i].end(),cmp);
52         }
53         priority_queue<node> q;
54         ans.push_back(0);
55         for(int i=1;i<=n;i++)
56         {
57             int x,y,z;
58             for(int j=0;j<m;j++)
59             {
60                 z=a[i][j]+ans[0];
61                 q.push(node(0,j,z));
62             }
63             while(d.size()<k&&!q.empty())
64             {
65                 node e=q.top();q.pop();
66                 d.push_back(e.val);
67                //printf("%d %d\n",cnt,d[cnt]);
68                 //cnt++;
69                 if(e.i+1<k&&i!=1)
70                     q.push(node(e.i+1,e.j,ans[e.i+1]+a[i][e.j]));
71             }
72             while(!q.empty()) q.pop();
73             ans.assign(d.begin(),d.end());
74             d.clear();
75         }
76         ll sum=0;
77         for(int i=0;i<k;i++)
78             sum+=ans[i];
79         printf("%lld\n",sum);
80     }
81 }

 

2017 ECJTU ACM 程序设计竞赛

原文:http://www.cnblogs.com/stranger-/p/7875446.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!