算法设计实验报告参考模板Word文档下载推荐.docx
- 文档编号:17956156
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:13
- 大小:53.95KB
算法设计实验报告参考模板Word文档下载推荐.docx
《算法设计实验报告参考模板Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《算法设计实验报告参考模板Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
•将运动员从1到N编号。
分析、证明
整个赛程,当N为偶数的时候,N-1天能够结束,
而当N为奇数的时候,只能在至少N天结束,、
因为,由已知
“每个运动员要和所有其他运动员进行一次比赛”则每个运动员总共进行N-1场,又由每一场有两个运动员参加,N个运动员就进行了M=[N*(N-1)]/2,又因为已知“要求每个运动员每天只进行一场比赛”则没人每天只能进行1场,所有运动员为N,每一场由两个运动员参加,当N为偶数的时候,每天只能出现的场数为N/2场,推出至少的天数为M/(N/2)=N-1场。
当N为奇数的时候,由于每个运动员每天只能进行一场,所以每天能进行的总场数最多只能为(N-1)/2场,则整个赛程的天数最少需要天数M/[(N-1)/2]=N天
总体思路:
按分治策略,将所有分为两半,n个选手可以通过n/2个选手设计的比赛日程表来决定。
递归地用一分为二的略对选手进行分割,直到只剩下两个选手。
对于N为奇数的情况可以虚拟多一个选手,使其编程N+1个选手的日程表,最然后忽略虚拟运动员参与的比赛。
对于分割时候N/2的情况也做特殊处理,前n/2轮比赛空选手与下一个未参赛的选手进行比赛
代码实现
void
match(int
a[][N],
int
k)
...{
n=1,
m=1;
for
(int
i=1;
i<
=k;
i++)
n
*=
2;
for(int
i=0;
n;
a[i][0]=i+1;
s=0;
s<
k;
s++)
//
k个阶段,从左到右
/=
t=0;
t<
t++)
每个阶段有t次循环
j=m;
j<
2*m;
j++)
i=m;
a[i-m+2*t*m][j]
=
a[i+2*t*m][j-m];
a[i+2*t*m][j]
a[i-m+2*t*m][j-m];
}
}
m
测试数据、运行结果
Pleaseinput:
3
Theresultis:
3
4
复杂度分析
T(n)∈O(n^2)
二、动态规划算法:
问题描述:
数字三角形问题
给定一个由n行数字组成的数字三角形,如图。
设计一个算法,计算出从三角形的顶至底的一条路径,是该路径经过的数字总和最大。
分析设计:
动态规划:
与分治法相似,把问题分解按层次分成子问题,直到可以直接求解的子问题,然后一级一级地向上求解。
与分治法的出别在于:
动态规划适用有许多重复子问题出现的问题,它保留已求出问题的解。
满足动态规划需符合的条件
1)最优化原理:
一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。
简而言之,一个最优化策略的子策略总是最优的。
对于给定的由n行数字组成的数字三角形,计算从三角形的底至顶的路径经过的数字和的最大值。
代码实现与结果:
#include"
stdio.h"
voidmain()
{
inti,j,n,a[100][100];
intM(intn,inta[100][100]);
FILE*fp1,*fp2;
if((fp1=fopen("
input.txt"
"
r"
))==NULL)
{
printf("
filecannotbeopened\n"
);
//exit
(1);
}
fscanf(fp1,"
%d"
&
n);
for(i=0;
for(j=0;
=i;
fscanf(fp1,"
a[i][j]);
if((fp2=fopen("
output.txt"
w"
fprintf(fp2,"
%d\n"
M(n,a));
intM(intn,inta[100][100])
{
inti,j;
intm[100][100];
intMAX(inta,intb);
for(i=n-1;
i>
=0;
i--)
for(j=0;
{
if(i==n-1)
m[i][j]=a[i][j];
else
m[i][j]=MAX(m[i+1][j]+a[i][j],m[i+1][j+1]+a[i][j]);
}
returnm[0][0];
intMAX(inta,intb)
if(a>
=b)
returna;
else
returnb;
/*
Input:
5
7
38
810
2744
45265
*/
Output:
30
算法复杂度:
O(T(n)∈O(n^2))
三、贪心算法
删数问题
给定n位正整数a,去掉其中期任意k≤n个数字后,剩下的数字按原次序排列组成一个新的正整数。
对于给定的n为正整数a和正整数k,设计一个算法找出剩下的数字组成的新数最小的删数方案。
分析证明:
贪心算法总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
满足贪心算法两个基本要素
1)、贪心选择性质:
选择具有无后效性,即不依赖与以后将要作出的选择。
问题的整体最优解可通过一系列的局部最优选择来达到。
证明方法:
用归纳法证明此问题的最优解包括一个贪心选择的解。
2)、最优子结构性质
一个问题的最优解包括其子问题的最优解。
算法设计:
对于给定的正整数a,计算删去k个数字后得到的最小数。
数据输入:
第一行是1个正整数a。
第二行是正整数k
算法实现代码与结果:
#include<
iostream>
usingnamespacestd;
charnum[100];
ints,len,i,j,k;
intmain()
cin>
>
num>
s;
len=strlen(num);
for(i=0;
i<
i++)
{
for(j=0;
j<
len-1;
j++)
if(num[j]>
num[j+1])
{
for(k=j;
k<
k++)
num[k]=num[k+1];
break;
}
len--;
}
if(len<
=0)
cout<
<
0;
else
for(i=0;
len;
cout<
num[i];
cout<
"
\n"
;
return0;
T(n)∈O(n^2)
四、回溯法
工作分配问题
设有n件工作分配给n个人。
将工作i分配给第j个人所需的费用为cij。
试设计一个算法为每一个人都分配1件不同的工作,并使总费用达到最小。
设计一个算法,对于给定的工作费用,计算最佳工作分配方案,使总费用达到最小。
输入:
第一行有一个正整数n
(1≤n≤20)。
接下来的n行,每行n个数,表示工作费用。
回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。
算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。
如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;
否则,进入该子树,继续按深度优先策略搜索。
算法代码与结果:
#include"
string.h"
malloc.h"
int**aray;
int*list;
intnumber;
intfinal_cost=0;
intcurrent_cost=0;
voidassign(int);
voidswap(int*,int*);
voidassign(intk){
inti;
if(k>
=number){
final_cost=current_cost;
else{
for(i=k;
number;
i++){
current_cost+=aray[k][list[i]];
if(current_cost<
final_cost){
swap(&
list[k],&
list[i]);
assign(k+1);
swap(&
}
current_cost-=aray[k][list[i]];
voidswap(int*a,int*b){
inttemp;
temp=*a;
*a=*b;
*b=temp;
main()
intm;
scanf("
m);
while(m--)
&
number);
aray=(int**)malloc(sizeof(int*)*number);
list=(int*)malloc(sizeof(int)*number);
list[i]=i;
aray[i]=(int*)malloc(sizeof(int)*number);
for(i=0;
for(j=0;
{
scanf("
aray[i][j]);
final_cost+=aray[i][i];
assign(0);
final_cost);
free(list);
free(aray);
五、分支限界法
在n*n的国际象棋棋盘上摆下n个后,使所有的后都不能攻击到对方,找出所有符合要求的情况。
在n×
n格的棋盘上放置彼此不受攻击的n个皇后。
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线的棋子。
也就是说,n后问题等价于在n×
n格的棋盘上放置n个皇后,任何两个皇后不放在同一行或同一列或同一斜线上。
n后问题是一个路径问题。
国际象棋的规则就是限界函数的约束条件。
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性产生其所有儿子结点。
在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。
这个过程一直持续到找到所需的解或活结点表为空时为止。
n后问题的解空间树是一棵排列树,一旦一种组合是一种解,则解与解之间不存在优劣的分别。
用分支限界法,在解空间树的第一层就会产生n个活结点,如果不考虑剪枝,将在第二层产生n*(n-1)个活结点,如此下去对队列空间的要求太高。
n后问题不适合使用分支限界法处理的根源是它需要找处所有解的组合,而不是某种最优解(事实上也没有最优解可言)。
分支限界法则可以被这样表述。
拿来一个棋盘,摆下一只后;
再拿一个棋盘,再摆一只;
待到每个棋盘都有一只后以后,每个棋盘又被分解成更多的盘面。
算法实现代码与结果
#include<
stdio.h>
constintN=20;
inta_xy[N][2];
longsum;
intn;
voidn_queue(intm)
if(m>
=n)
/*
printf("
the%ldthmethod:
sum+1);
i++,printf("
))
if(j==a_xy[i][1])printf("
*"
elseprintf("
0"
i++)printf("
--"
sum++;
return;
boolt1;
for(j=0,t1=true;
m;
if(a_xy[j][1]==i||abs(a_xy[j][0]-m)==abs(a_xy[j][1]-i))
{t1=false;
break;
if(t1)
a_xy[m][0]=m;
a_xy[m][1]=i;
n_queue(m+1);
intmain()
while(true)
pleaseinputn:
sum=0;
n_queue(0);
theresultis:
%ld\n"
sum);
return0;
六、总结:
通过本课程的学习,了解了一些基本的算法以及他们的实现和应用,并学会了算法的分析与设计,解决一些基本问题。
但更多还有待进一步研究与提高。
参考文献
[1]计算机算法设计与分析(第三版)王晓东
[2]算法设计与实验题解王晓东
[2]算法分析与设计
友情提示:
范文可能无法思考和涵盖全面,供参考!
最好找专业人士起草或审核后使用,感谢您的下载!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 设计 实验 报告 参考 模板