poj 2442 Sequence(堆)
2017-11-08 23:22
316 查看
题面
题意
给出一个m*n的矩阵,每行选择一个数相加,问所得的n个最小值是多少。方法
将所有数一起处理必然会有漏洞,无法保证答案的正确或是时间,故可以一行一行处理,因为多考虑一行后的n个最小数必然由考虑这一行之前的n个最小值与这一行上的一些数相加得到,因而每次只需记录考虑上面几行后的最小值即可,问题就转换为了求两行上一些数相加的所有和中的最小的n个值。这个问题可以用堆解决,因为两个序列都是升序,若a[i]+b[j]是其中一个最小值,那么a[i-1]和b[j-1]也是,以此性质,我们可以把a[1]与b中所有数的和加到堆里,每取出最小值,把a序列中的下一个数与b中那个数的和加到堆里:
例:a[1]+b[1]出堆后,将a[2]+b[1]加到堆里。
代码
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #define P pair<int,int> #define mp make_pair #define fi first #define se second using namespace std; int T,n,m,num[110][2010],ans[2010],now[2010],tmp[2010]; priority_queue<P,vector<P>,greater<P> >pq; P tmp2; void read(int &u) { u=0; register char ch=getchar(); while(ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') { u*=10,u+=ch-'0',ch=getchar(); } } int main() { register int i,j,k; cin>>T; while(T--) { read(m),read(n); for(i=1;i<=m;++i) { for(j=1;j<=n;++j) { read(num[i][j]); } sort(num[i]+1,num[i]+n+1); } for(i=1;i<=n;++i) { ans[i]=num[1][i]; } for(i=2;i<=m;++i) { for(;!pq.empty();pq.pop()); for(j=1;j<=n;++j) { now[j]=1; pq.push(mp(ans[j]+num[i][1],j)); } for(j=1;j<=n;++j) { ans[j]=pq.top().fi; tmp2=pq.top(); pq.pop(); now[tmp2.se]++; tmp2.fi+=num[i][now[tmp2.se]]-num[i][now[tmp2.se]-1]; pq.push(tmp2); } } for(i=1;i<=n;++i) { printf("%d ",ans[i]); } puts(""); } }
相关文章推荐
- POJ 2442 Sequence(堆的应用)
- poj 2442 Sequence
- 【POJ】 2442——Sequence【STL—优先队列】
- POJ 2442 Sequence
- POJ 2442 Sequence(优先队列)
- POJ 2442 Sequence(stl+优先队列||堆)
- POJ-2442 Sequence(优先队列)
- Poj 2442 Sequence
- POJ 2442 Sequence
- POJ 2442 Sequence (堆)
- POJ 2442 Sequence (堆)
- poj 2442 Sequence
- POJ 2442 Sequence
- POJ-2442-Sequence
- poj 2442 Sequence(优先队列)
- POJ 2442 Sequence
- POJ 2442 Sequence
- POJ 2442 Sequence
- poj 2442 Sequence 堆
- POJ 2442 Sequence