算法实验报告.docx
- 文档编号:4263292
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:30
- 大小:202.49KB
算法实验报告.docx
《算法实验报告.docx》由会员分享,可在线阅读,更多相关《算法实验报告.docx(30页珍藏版)》请在冰豆网上搜索。
算法实验报告
算法实验报告
目录
实验一分治与递归3
一、实验目的3
二、实验内容3
三、实验步骤3
四、实验代码3
五、运行截图6
六、实验体会6
实验二动态规划算法7
一、实验目的7
二、实验内容7
三、实验步骤7
四、实验代码7
五、运行截图10
六、实验体会11
实验三、贪心算法12
一、实验目的12
二、实验内容12
三、实验步骤12
四、实验代码12
五、运行截图17
六、实验体会18
实验四回溯算法和分支限界法19
一、实验目的19
二、实验内容19
三、实验步骤19
四、实验代码19
五、运行截图26
六、实验体会27
实验一分治与递归
一、实验目的
1、熟悉C、C++语言的集成的开发环境
2、加深对递归过程的理解
3、掌握棋盘覆盖问题的算法
4、初步掌握分治算法
二、实验内容
分析掌握棋盘覆盖问题和整数划分问题的递归算法
三、实验步骤
1、理解算法的思想和问题的要求。
2、编程实现题目的要求。
3、上机输入和调试自己的所编的程序。
4、验证分析实验结果。
5、整理出实验报告
四、实验代码
1、棋盘覆盖问题
#include
#defineboard_size8
intboard[board_size][board_size];
usingnamespacestd;
inttile=0;
voidchessBoard(inttr,inttc,intdr,intdc,intsize)
{
if(size==1)return;
intt=tile++,//L型骨牌号
s=size/2;//分割棋盘
//覆盖左上角子棋盘
if(dr
//特殊方格在此棋盘中
chessBoard(tr,tc,dr,dc,s);
else{//此棋盘中无特殊方格
//用t号L型骨牌覆盖右下角
board[tr+s-1][tc+s-1]=t;
//覆盖其余方格
chessBoard(tr,tc,tr+s-1,tc+s-1,s);}
//覆盖右上角子棋盘
if(dr
//特殊方格在此棋盘中
chessBoard(tr,tc+s,dr,dc,s);
else{//此棋盘中无特殊方格
//用t号L型骨牌覆盖左下角
board[tr+s-1][tc+s]=t;
//覆盖其余方格
chessBoard(tr,tc+s,tr+s-1,tc+s,s);}
//覆盖左下角子棋盘
if(dr>=tr+s&&dc //特殊方格在此棋盘中 chessBoard(tr+s,tc,dr,dc,s); else{//用t号L型骨牌覆盖右上角 board[tr+s][tc+s-1]=t; //覆盖其余方格 chessBoard(tr+s,tc,tr+s,tc+s-1,s);} //覆盖右下角子棋盘 if(dr>=tr+s&&dc>=tc+s) //特殊方格在此棋盘中 chessBoard(tr+s,tc+s,dr,dc,s); else{//用t号L型骨牌覆盖左上角 board[tr+s][tc+s]=t; //覆盖其余方格 chessBoard(tr+s,tc+s,tr+s,tc+s,s);} } voidmain() { intk,dr,dc; inttr=0,tc=0; k=board_size; cout<<"请输入特殊方格的行号: "; cin>>dr; cout<<"请输入特殊方格的列号: "; cin>>dc; chessBoard(k,tr,tc,dr,dc); inti,j; for(i=0;i<=board_size;i++) {for(j=0;j cout< printf("\n"); } } 2、整数划分问题 #include usingnamespacestd; intq(intn,intm) { if((n<1)||(m<1))return0; if((n==1)||(m==1))return1; if(n if(n==m)returnq(n,m-1)+1; returnq(n,m-1)+q(n-m,m); } intmain() { intn,m; cout<<"n="; cin>>n; cout<<"m="; cin>>m; cout< cout< return0; } 五、运行截图 六、实验体会 通过本次试验,熟悉C、C++语言的集成的开发环境,加深对递归过程的理解,并且掌握棋盘覆盖问题的算法,初步掌握分治算法。 实验二动态规划算法 一、实验目的 1、熟悉最长公共子序列问题的算法 2、初步掌握动态规划算法 3、熟悉最长最大字段和问题的算法 4、进一步掌握动态规划算法 二、实验内容 1、找最长公共子序列问题 2、最大字段和的问题 三、实验步骤 1、理解算法的思想和问题的要求。 2、编程实现题目的要求。 3、上机输入和调试自己的所编的程序。 4、验证分析实验结果。 5、整理出实验报告 四、实验代码 1、最长公共子序列 #include #include usingnamespacestd; #defineN105 intdp[N+1][N+1]; charstr1[N],str2[N]; intmark[N+1][N+1]; intmaxx(inta,intb) {if(a>b)returna;returnb;} voidLCSL(intlen1,intlen2) { inti,j; intlen=maxx(len1,len2); for(i=0;i<=len;i++) { dp[i][0]=0;dp[0][i]=0; } for(i=1;i<=len1;i++) for(j=1;j<=len2;j++) { if(str1[i-1]==str2[j-1]) { dp[i][j]=dp[i-1][j-1]+1; mark[i][j]=1; } else { inta=dp[i-1][j]; intb=dp[i][j-1]; dp[i][j]=maxx(a,b); if(a>=b) mark[i][j]=2; else mark[i][j]=3; } } } voidLCS(inti,intj) { if(i==0||j==0) return; if(mark[i][j]==1) { LCS(i-1,j-1); cout< } elseif(mark[i][j]==2) { LCS(i-1,j); } else LCS(i,j-1); } intmain() { cout<<"请输入第一个序列: "; cin>>str1; cout<<"请输入第二个序列: "; cin>>str2; memset(mark,0,sizeof(mark)); intlen1=strlen(str1); intlen2=strlen(str2); LCSL(len1,len2); cout< if(dp[len1][len2]! =0) { LCS(len1,len2); cout< } system("pause"); return0; } 2、最大字段和 #include usingnamespacestd; intmaxSubItem(int*a,intlow,inthigh) { ints1,s2,s31,s32,i,j; intsum; intmid=(low+high)/2; if(low==high) returna[low]; else { s1=maxSubItem(a,low,mid); s2=maxSubItem(a,mid+1,high); i=mid; s31=a[mid]; while((s31+a[i-1]>s31)&&(i>low)) { s31+=a[i-1]; i--; } j=mid+1; s32=a[mid+1]; while((s32+a[j+1]>s32)&&(j { s32+=a[j+1]; j++; } sum=s31+s32; if(sum if(sum } returnsum; } voidmain() {intn; cout<<"请输入序列元素个数n: "; cin>>n; inta[20]; for(inti=0;i cout<<"ThemaximumsubItemis"< } 五、运行截图 六、实验体会 通过本次试验,熟悉了最长公共子序列问题的算法,初步掌握动态规划算法,最长最大字段和问题的算法,并且进一步掌握动态规划算法。 实验三、贪心算法 一、实验目的 1、熟悉多机调度问题的算法 2、初步掌握贪心算法 3、熟悉贪心算法的基本原理与适用范围 4、使用贪心算法编程,求解最小生成树问题 二、实验内容 1、多机调度 2、用贪心算法求解最小生成树 三、实验步骤 1、理解算法的思想和问题的要求。 2、编程实现题目的要求。 3、上机输入和调试自己的所编的程序。 4、验证分析实验结果。 5、整理出实验报告 四、实验代码 1、作业调度问题 #include #include"iostream.h" #include"conio.h" #definemaxWork100 #definemaxMachine100 classmachineWork { public: machineWork(void); ~machineWork(void); voidSetMachine(intmachine); voidSetWorks(doubletimes[],intworks); boolArrange(); voidSort(inttimeId[]); voidPrint(); private: doubletimesUnsorted[maxWork]; intgraph[maxMachine][maxWork]; doublemachinesTime[maxMachine]; intmachines; intworks; }; machineWork: : machineWork(void) { } machineWork: : ~machineWork(void) { } voidmachineWork: : Sort(inttimeId[]) { for(inti=0;i timeId[i]=i; for(i=0;i { doublemin=timesUnsorted[timeId[i]]; intp=i; for(intj=i+1;j { if(this->timesUnsorted[timeId[j]]>min) { min=this->timesUnsorted[timeId[j]]; p=j; } } intt=timeId[i]; timeId[i]=timeId[p]; timeId[p]=t; } } voidmachineWork: : SetMachine(intmachines) { this->machines=machines; } voidmachineWork: : SetWorks(doubletimes[],intworks) { this->works=works; for(inti=0;i timesUnsorted[i]=times[i]; } boolmachineWork: : Arrange() { inttimeId[maxWork]; Sort(timeId); //某一工作安排后,对机器的工作时间进行排序 //index[i]保存机器编号 intindex[maxMachine]; //graph[i][0]表示机器i中已经安排了几项任务 for(inti=0;i graph[i][0]=0; //机器已经安排的工作时间 for(i=0;i machinesTime[i]=0.0; //index[0]所指向的graph[index[0]][0]的值是最小的 for(i=0;i index[i]=i; //给i号作业分配机器 for(i=0;i { //把作业分配给index[0]所指向的机器 graph[index[0]][0]++; graph[index[0]][graph[index[0]][0]]=timeId[i]; machinesTime[index[0]]+=timesUnsorted[timeId[i]]; //对机器的已经安排的工作时间进行排序 intj=0; while(j { intt=index[j]; index[j]=index[j+1]; index[j+1]=t; j++; } } returntrue; } voidmachineWork: : Print() { for(inti=0;i printf("工作%d所需要的时间%5.f\n",i,timesUnsorted[i]); printf("\n"); for(i=0;i { printf("机器%d工作总时间%.f=",i,machinesTime[i]); printf("%.f",timesUnsorted[graph[i][1]]); for(intj=2;j<=graph[i][0];j++) printf("+%.f",timesUnsorted[graph[i][j]]); printf("\n"); } printf("\n"); for(i=0;i { printf("机器%d上的工作安排",i); for(intj=1;j<=graph[i][0];j++) printf("%d",graph[i][j]); printf("\n"); } } intmain(intargc,char*argv[]) { inta,b; cout<<"请输入工作数: "; cin>>a;cout< doublet[maxWork]; for(inti=0;i ";cin>>t[i];cout< machineWorkw; cout<<"请输入机器数: "; cin>>b;cout< w.SetMachine(b); w.SetWorks(t,a); w.Arrange(); w.Print(); getch(); return0; } 2、用贪心算法求解最小生成树 #include usingnamespacestd; voidgreedy(intt[],intn,intm); intmain() { intn=7,m=3,t[]={2,15,5,17,7,6,4};//待分配的工作 greedy(t,n,m); return0; } voidgreedy(intt[],intn,intm) { intflagn,flagm; intM[]={0,0,0,0,0,0,0,0}; for(inti=0;i { intmax=0,min=10000; flagn=0; flagm=0; for(intj=0;j { if(max { max=t[j]; flagn=j; } } for(j=0;j { if(M[flagm]>M[j]) { flagm=j; } M[flagm]=M[flagm]+t[flagn]; t[flagn]=0; cout< } } } 五、运行截图 六、实验体会 通过本次试验,熟悉了多机调度问题的算法,初步掌握贪心算法,并且学会了使用贪心算法编程,求解最小生成树问题。 实验四回溯算法和分支限界法 一、实验目的 1、掌握符号三角形问题的算法 2、初步掌握回溯算法 3、掌握0—1背包问题的回溯算法 4、进一步掌握回溯算法 二、实验内容 1、符号三角形问题 2、0-1背包问题 三、实验步骤 1、理解算法的思想和问题的要求。 2、编程实现题目的要求。 3、上机输入和调试自己的所编的程序。 4、验证分析实验结果。 5、整理出实验报告 四、实验代码 1、符号三角形问题 #include usingnamespacestd; classTriangle { friendintComputer(int); private: voidBacktrack(intt); intn,//第1行符号的个数 half,//每个三角形总符号数的一半 count,//统计减号的个数 **p;//指向三角形的二维指针 longsum;//统计符合条件的的三角形的个数 }; voidTriangle: : Backtrack(intt) { inti,j,k,s,f; if((count>half)||(t*(t-1)/2-count>half)) return;//如果加号或减号的个数大于符号三角形中总符号数的一半则退出函数 if(t<=n)//回溯条件直到n for(i=0;i<2;i++) { p[1][t]=i; count+=i; for(j=2;j<=t;j++) { p[j][t-j+1]=p[j-1][t-j+1]^p[j-1][t-j+2];//判断下行符号 count+=p[j][t-j+1]; } if(t>=n) {//输出符合条件的三角形 f=0; for(j=1;j<=t;j++) for(k=1;k<=t-j+1;k++) f+=p[j][k]; if(f==half) {//如果减号是总符号数的一半则输出并将sum加1 cout<<"第"<<++sum<<"个三角形"<<'\n'; for(j=1;j<=t;j++) { for(s=1;s for(k=1;k<=t-j+1;k++) { if(p[j][k]==1) cout<<"-";//3个空 如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。 copyright@ 2008-2022 冰点文档网站版权所有 经营许可证编号:鄂ICP备2022015515号-1