1. 程式人生 > >[uva11997]k個最小和

[uva11997]k個最小和

eof 枚舉 int 一個 a.out sin i++ vector pop

一個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個最小和