题解 P1392 【取数】

2018-08-12 00:00:00 题解

看着楼下的题解,竟然没有用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

天天下载

2025-01-01 18:09:11

感谢分享,谢谢站长