问题
给定n个圆的半径序列,将它们放到矩形框中,各圆与矩形底边相切,求具有最小排列长度的圆排列。
解析
圆排列问题的解空间是一棵排列树。按照回溯法搜索排列树的算法框架,设开始时a=[r1,r2,……rn]是所给的n个元的半径,则相应的排列树由a[1:n]的所有排列构成。
计算圆在当前圆排列中的横坐标由sqrt((r1+r2)2-(r1-r2)2)推导出2 * sqrt(r1 * r2)
设计
//核心伪代码
void dfs(int t)
{
if (t == n + 1) 计算排列长度
else
for(int j=t;j<=n;j++)
{
swap(r[t],r[j]);//确定当前第t个圆的半径,或者说,对第t个圆进行了选择
求出第t个圆选入后,排列的长度,可称之为当前排列长度
找到界限条件,如果满足条件
{
入选所选的第t个圆;
开始深入到第t+1个圆,即dfs(t+1)
}
swap(r[t],r[j]); 恢复
}
}
时间复杂度
由排列组合可知,生成一个长度为n的序列的全排列的时间复杂度为O(n!)
由于每次都需要计算圆排列长度,此时的时间复杂度为O(n)。
- 综上,该算法的时间复杂度为O(n*n!)。