[uva11997]k个最小和
Posted Konjak谷弱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[uva11997]k个最小和相关的知识,希望对你有一定的参考价值。
一个k*k的矩阵,每行选取一个数相加则得到一个和,求最小的前k个和。
k<=750
已知前m行最小的前k个和d[1]…d[k],则前m+1行最小的前k个和都必定是d[i](i<=k)+a[m+1][x]。排序,枚举x,用优先队列处理。
学会了个小技巧:
node形式的优先队列,想直接插入元素组成node
struct node里加一句node (int sum,int b):sum(sum),b(b) {} 实际调用:q.push(node(sum,b));
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<cmath> 7 #include<vector> 8 #include<map> 9 #include<queue> 10 using namespace std; 11 12 const int K=800; 13 int k,a[K][K]; 14 bool cmp(int x,int y){return x<y;} 15 16 struct node{ 17 int sum,b; 18 node (int sum,int b):sum(sum),b(b) {} 19 bool operator < (const node &x) const { 20 return sum > x.sum; 21 } 22 }; 23 24 priority_queue<node> q; 25 26 void my_merge(int *A,int *B) 27 { 28 while(!q.empty()) q.pop(); 29 for(int i=1;i<=k;i++) q.push(node(A[i]+B[1],1)); 30 for(int i=1;i<=k;i++) 31 { 32 node x=q.top();q.pop(); 33 A[i]=x.sum; 34 if(x.b<=k-1) q.push(node(x.sum-B[x.b]+B[x.b+1],x.b+1)); 35 } 36 } 37 38 int main() 39 { 40 // freopen("a.in","r",stdin); 41 // freopen("a.out","w",stdout); 42 43 while(scanf("%d",&k)!=EOF) 44 { 45 for(int i=1;i<=k;i++) 46 for(int j=1;j<=k;j++) 47 scanf("%d",&a[i][j]); 48 49 sort(a[1]+1,a[1]+k+1,cmp); 50 for(int i=1;i<k;i++) 51 { 52 sort(a[i+1]+1,a[i+1]+k+1,cmp); 53 my_merge(a[1],a[i+1]); 54 } 55 printf("%d",a[1][1]); 56 for(int i=2;i<=k;i++) printf(" %d",a[1][i]);printf("\n"); 57 } 58 59 return 0; 60 }
以上是关于[uva11997]k个最小和的主要内容,如果未能解决你的问题,请参考以下文章
UVA 11997 K Smallest Sums 优先队列+归并 STL
UVA.11997- K Smallest Sums, OJ4TH.368 - Magry's Sum I