堆(2)

今天我们还是学了堆这个概念,不过题目的难度也有所提高,并不是模板题那么简单。下面上一道题目:

取数

题目描述

在一个n行m列的数阵中,你须在每一行取一个数(共n个数),并将它们相加得到一个和。对于给定的数阵,请你输出和前k小的取数方法。

输入输出格式

输入格式:

第一行,三个数n,m,k。

第2~n+1行,每行m个正整数

输出格式:

一行共k个数,代表在每一行取一个数前k小的加和

输入输出样例

输入样例#1:
3 3 2
1 2 3
6 3 5
4 1 2
输出样例#1:
5 6

说明

对于20%的数据,n≤8

对于100%的数据,n≤800,k≤m≤800

思路 (此题只讲思路,不给代码)

这题看起来并不是很难,毕竟第一个数还是很好求的嘛。。但是接下来就比较棘手了。

因为这题有n行,所以我们可以先做一个两行的(为方便计算,我把第一行记作a[],第二行记作b[]),得出来的值再形成一行,依次做两行,就可以把n行都做完了。

第一个最小的肯定是第一行的第一个数加上第二行的第一个数,于是把a[1]+b[1]入堆。

但是第二个最小的可以是a[1]+b[2],也可以是a[2]+b[1],怎么办呢?欸,我可以都入堆啊。于是可以得到,每次发现a[i]+b[j]是最小值时,我就可以将a[i+1]+b[j]和a[i]+b[j+1]入堆。

但是这样做还是有点问题,比如a[i-1]+b[j]和a[i]+b[j-1]都可以得到a[i]+b[j],将其入堆,那不就重复入堆了吗?

于是我就还需要一个标记,这样一来,我入堆的东西就可以是一个结构体了(没想到吧),一个存i,一个存j,一个存值,一个存标记,然后根据值的大小来执行四个操作,具体操作见我前面的随笔

然后这个用结构体入堆的步骤,我可以给你一个简便的方法:

kpush((PP){a[i]+a[j],1,1,0});//前面的小括号里是结构体名,后面的大括号里填结构体的参数

这样就可以直接入堆。

最后还是推荐一个自己建堆的网站:自己建堆

猜你喜欢

转载自www.cnblogs.com/manmanjiangQwQ/p/9114926.html
今日推荐