对于给定的自然数n,为了生成所有的最小堆,例如对于n = 4,总堆是3,对于更大的n值,应该生成有限的堆,如20-30,超过合理的interva
1 3 2 4
我提出了以下想法来生成所有堆。 从i开始循环从1到n并将i推送到矢量也将其标记为已使用。现在递归函数并且如果标记为continue,那么在添加i的情况下,如果父级已经更大,则继续使用下一个值,因为这将构成无效堆。请参考下面的代码,我想我做了一个糟糕的工作来解释。问题是n = 16或n = 17需要太多时间。我尝试通过减少计算来优化它,其中向量的第一个元素不是1。
我想提出改进效率的建议或任何其他算法来有效地生成所有最小堆。
#include <bits/stdc++.h>
using namespace std;
vector<int> v;
int n,k ;
int cnt = 0 ;
vector<int> p(100,0);
void gen(){
if(v.size() == n){
cnt++;
if(cnt % k == 0){
for(auto x : v){
cout<<x<<" ";
}
cout<<endl;
}
}
else{
for(int i = 1 ; i <= n ; i++){
if(v.size() and v[0] != 1 ){
return ;
}
if(p[i])
continue;
int x = v.size();
int parent ;
if(x & 1){
parent = (x-1)/2;
}
else
parent = (x-2)/2;
if(x==0)
parent = 0 ;
if(v.size() and v[parent] > i ){
continue ;
}
p[i] = 1;
v.push_back(i);
gen();
p[i] = 0;
v.pop_back();
}
}
}
int main(){
//ios_base::sync_with_stdio(false);cin.tie(NULL);
cin>>n>>k;
gen();
cout<<"TOTAL "<<cnt<<endl;
}
答案 0 :(得分:0)
当您处理10个或更多项目时,一种可能效果很好的简单方法是随机化一个数组,然后使用build-heap
函数将其转换为堆。泡沫,冲洗,重复。
您每次都必须检查新堆是否与任何现有堆匹配,但如果您只生成20或30堆,则不会是巨大的性能问题。
我承认这个解决方案不是最有效的,但它应该能够合理地快速完成工作。
供参考,build-heap
功能:
for (int i = v.size/2; i >= 0; --i)
{
siftDown(i);
}