圆排列问题

问题描述:

给定n个大小不等的圆 c1 c2 c3 c4 要将n个圆排进一个矩形框中,且要求底边相切。找出有最小长度的圆排列。

例如:当n=3,且所给的3个圆半径分别为1,1,2时,这3个圆的最小长度的圆排列 最小长度为2+4根号2.

 

算法设计:

设开始的a =【r1,r2,r3,r4...rn】是所给的n歌圆半径。

CirclePerm(n,a)返回最小长度。

Center计算当前选择的圆中心的横坐标。

Compute计算当前圆排列的长度。

数组r当前圆排列。

 

算法描述:


#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
class Circle{

friend float CirclePerm(int ,float *);

private:
float Center(int t);
void Compute(void);
void Backtrack(int t);
float min,*x,*r;
int n;
};
float Circle::Center(int t)
{
float temp = 0;
for(int j=1;j<t;j++)
{
float valuex=x[j]+2.0*sqrt(r[t]*r[j]);
if(valuex > temp)
temp = valuex;
}
return temp;
}
void Circle::Compute(void)
{
float low = 0,
high = 0;
for(int i=1;i<=n;i++)
{
if(x[i]-r[i] < low)
low = x[i]-r[i];
if(x[i]+r[i] > high)
high = x[i]+r[i];
}
if(high-low < min)
min = high-low;
}
void Circle::Backtrack(int t)
{
if(t>n)
Compute();
else
for(int j=t;j<=n;j++)
{
swap(r[t],r[j]);
float centerx = Center(t);
if(centerx+r[t]+r[1]<min)
{
x[t] = centerx;
Backtrack(t+1);
}
swap(r[t],r[j]);
}
}
float CirclePerm(int n,float *a)
{
Circle X;
X.n = n;
X.r = a;
X.min = 100000;
float *x = new float [n+1];
X.x = x;
X.Backtrack(1);
delete [] x;
return X.min;
}
int main()
{
int n;
cout<<"please enter your numbers!:";
cin>>n;
float *p = new float [n+1];
cout<<"please enter your circles:";
for(int i=0;i<n;i++)
{
cin>>p[i];
}
cout<<CirclePerm(n,p)<<endl;
delete [] p;
return 0;
}

时间: 2024-10-10 09:19:00

圆排列问题的相关文章

排列与组合的一些定理

一,加法原理与乘法原理 加法原理与乘法原理是排列与组合的基础.加法原理本质上是分类,乘法原理本质上是分步. 分类,就是把一个集合(某事物)分成互不相交的若干独立的部分.比如,概率论中的全概率公式就将事件分成”全划分“ 分类思想可以简化程序的时间复杂度.比如:最短路径算法-Dijkstra算法的应用之单词转换(词梯问题) 分步,就是第一步干嘛,第二步再干嘛……比如A地到D地,第一步:先到达B地:第二步,再到达C地 二,排列 P(n,r)表示从n个数中选择r个数的一个全排列 公式:P(n,r)=P(

多样的排列

圆排列:n个不同的元素取r个做圆排列. 每个圆排列可以从r个相邻的位置剪开从而得到r个不同的线性排列,所以圆排列数: ans = P(n, r) / r 项链排列:跟圆排列差不多,不过圆排列是平面的,所以翻转后是不同的,但项链是三维的,翻转后虽然从一面看起来跟刚才不一样了,但实际是算同一个,所以其排列数相当于圆排列的一半. 多重排列:n个可以重复的元素来进行排列,先给重复的元素加下标1,2,3-,然后按照正常的n个不同的元素来算,最后再除以重复的(这个应该知道怎么算吧,x个重复,就除以x!).

计算机算法基础 ——数学(排列组合函数)

一 排列 1.从n个元素中取r个元素排列的全体数目 Pnr=P(n,r)=n(n-1)(n-2)...(n-r+1)=n!/(n-r)!                  :例:n个球取r个放入r个不同盒子,每个盒子一个球,多少种放法 2. n个元素的全排列 Pnn=P(n,n)=n! 3.例:随机选n(n<365)个人,求其中至少有两人生日相同的概率. n个人的生日的序列数:365n n个人生日均不相同的概率:P(365,n) 故:1-P(365,n)/365n 4.圆排列 从n个元素中取r个

模板C++ 02数论算法 3排列与组合

2.3排列与组合 1.排列(在乎顺序) 全排列:n个人全部来排队,队长为n.第一个位置可以选n个,第二位置可以选n-1个,以此类推得:P(n,n)=n(n-1)(n-2)--3*2*1=n!(规定0!=1). 部分排列:n个人选m个来排队(m<=n).第一个位置可以选n个,第二位置可以选n-1个,以此类推,第m个(最后一个)可以选(n-m+1)个,得: 2.组合(不在乎顺序) n个人m(m<=n)个出来,不排队,不在乎顺序C(n,m).如果在乎排列那么就是P(n,m),如果不在乎那么就要除掉重

【数论】排列组合问题

排列 定义: 从n个不同元素中,任取m(m≤n,m与n均为自然数,下同)个元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列:从n个不同元素中取出m(m≤n)个元素的所有排列的个数,叫做从n个不同元素中取出m个元素的排列数,用符号 A(n,m)表示 公式: A(n,m)=n(n-1)*(n-2)*……*(n-m+1)= n!/(n-m)! PS:此外规定0!=1 特殊排列: 不全相异元素的排列: 在n个元素中 n1个元素彼此相同 有n2个元素彼此相同......有nm个元素彼

排列组合问题的一些整理

初步:加法原理和乘法原理 概念: 加法原理是分类计数原理,常用于排列组合中,具体是指:做一件事情,完成它有n类方式,第一类方式有M1种方法,第二类方式有M2种方法,--,第n类方式有Mn种方法,那么完成这件事情共有M1+M2+--+Mn种方法. 做一件事,完成它需要分成n个步骤,做第一 步有m1种不同的方法,做第二步有m2种不同的方法,--,做第n步有mn种不同的方法.那么完成这件事共有 N=m1×m2×m3×-×mn 种不同的方法. 这个感觉大家都知道(小学奥数就开始学了吧qwq),感觉没有什

回溯法 -数据结构与算法

1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能性.即避免不必要的搜索.这种方

HDU4372 Count the Buildings

There are N buildings standing in a straight line in the City, numbered from 1 to N. The heights of all the buildings are distinct and between 1 and N. You can see F buildings when you standing in front of the first building and looking forward, and

被虐的两道数论题

我说……我这么闲,那么……写篇日志吧,谨以此纪念我无限趋向于0的智商,那天……犯了个傻的两道题……顺便orz一下HGR以及HYY神犇……        Problem A:        给定n,k,求任意一个序列a,使得∏(1≤i≤k)(1+1/ai)=1+(2^k-1)/n.(1≤n≤2^31,1≤k≤31) 本来这题目是很水的……但是……我当即立断,机智地化了简:(Σ(b∈[1,k])ab1ab2ab3…abp)/∏(1≤i≤k)ai=(2^k+n-1)/n.随后我发现,ai与ai+1约分