看着楼下的题解,竟然没有用STL的?(听说是数据太强卡STL的优先队列,可是本蒟蒻不会手写堆而且我可不这么认为)我来一个STL版本。
sort+STL+DFS=Accpted
思路楼下的楼下讲得很好,如果还是有一点蒙请移步
P1631 序列合并
#include<bits/stdc++.h>
using namespace std;
priority_queue<int>w;
int m,n,k,a[805][805],gt[805],c[805],top;//gt数组计录每一行最小值的前缀和;
int get(int i)//第i行以下最小值的和
{
return gt[n]-gt[i];
}
void search(int t,int s)//DFS
{
for(int i=1;i<=m;i++)
{
s+=a[t][i];
if(s+get(t)>w.top()) return;//如果选择此数并且加上可能取得的最小值还是不够小,直接return;
if(t==n) if(s<w.top()) w.pop(),w.push(s);else;
else search(t+1,s);
s-=a[t][i];//回溯;
}
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>a[i][j];
sort(a[i]+1,a[i]+1+m);//排序
gt[i]=gt[i-1]+a[i][1];//处理前缀和
}
for(int i=1;i<=k;i++)
w.push(INT_MAX);//初始化
search(1,0);//DFS
/*因为是大根堆,所以反向输出*/
while(w.size()) c[++top]=w.top(),w.pop();
for(int i=k;i>=1;i--)
cout<<c[i]<<' ';
return true;
}
顺便附上一组很水的数据
比样例好
9 9 10
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9