大厦
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 }
时间: 2024-10-17 07:05:04