算法设计与分析课程设计
算法设计课程设计问题

算法设计课程设计问题一、教学目标本课程的教学目标是让学生掌握算法设计的基本概念和方法,培养学生的问题解决能力和创新思维能力。
具体包括以下三个方面的目标:1.知识目标:学生能够理解算法设计的基本概念,掌握常见的算法设计方法和技巧,了解算法分析的基本方法。
2.技能目标:学生能够运用算法设计方法解决实际问题,具备编写和调试算法代码的能力,能够进行算法性能分析和优化。
3.情感态度价值观目标:学生能够认识到算法设计在现代社会的重要性,培养对算法设计的兴趣和热情,树立正确的算法设计伦理观念。
二、教学内容本课程的教学内容主要包括算法设计的基本概念、常见的算法设计方法和技巧、算法分析的基本方法等。
具体安排如下:1.第一章:算法设计的基本概念,包括算法、输入、输出、有穷性、确定性等。
2.第二章:常见的算法设计方法,包括贪婪法、动态规划、分治法、回溯法等。
3.第三章:算法分析的基本方法,包括时间复杂度、空间复杂度、渐近符号等。
4.第四章:算法设计实例分析,包括排序算法、查找算法、图算法等。
三、教学方法为了实现本课程的教学目标,将采用多种教学方法相结合的方式进行教学。
具体包括以下几种方法:1.讲授法:通过讲解算法设计的基本概念和方法,使学生掌握算法的理论知识。
2.案例分析法:通过分析实际案例,使学生了解算法设计在实际问题中的应用。
3.实验法:通过编写和调试算法代码,培养学生的实际编程能力和算法设计技巧。
4.讨论法:通过分组讨论和课堂讨论,激发学生的创新思维和问题解决能力。
四、教学资源为了保证本课程的教学质量,将充分利用校内外教学资源。
具体包括以下几种资源:1.教材:选用国内外优秀的算法设计教材,作为学生学习的主要参考资料。
2.参考书:推荐学生阅读相关的算法设计参考书籍,丰富学生的知识体系。
3.多媒体资料:制作精美的课件和教学视频,提高课堂教学效果。
4.实验设备:提供充足的计算机设备,确保学生能够进行实验和实践。
五、教学评估本课程的评估方式将采用多元化的形式,以全面、客观、公正地评价学生的学习成果。
算法课设实验报告(3篇)

第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。
为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。
二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。
1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。
(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。
- 对每种算法进行时间复杂度和空间复杂度的分析。
- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。
(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。
- 编写三种排序算法的代码。
- 分析代码的时间复杂度和空间复杂度。
- 编写测试程序,生成随机测试数据,测试三种算法的性能。
- 比较三种算法的运行时间和内存占用。
2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。
(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。
- 分析贪心算法的正确性,并证明其最优性。
(3)实验步骤:- 分析活动选择问题的贪心策略。
- 编写贪心算法的代码。
- 分析贪心算法的正确性,并证明其最优性。
- 编写测试程序,验证贪心算法的正确性。
3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。
(2)实验内容:- 实现一个动态规划算法问题,如背包问题。
- 分析动态规划算法的正确性,并证明其最优性。
(3)实验步骤:- 分析背包问题的动态规划策略。
- 编写动态规划算法的代码。
- 分析动态规划算法的正确性,并证明其最优性。
- 编写测试程序,验证动态规划算法的正确性。
三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。
计算机算法设计与分析课程设计常规题目的(C及C++)代码集

合并排序1:#include<iostream>using namespace std;const int N=100;class list{public:int array[N];void input(int a);void merge(int arrayc[],int arrayd[],int l,int m,int r);void mergepass(int arrayx[],int arrayy[],int s);void mergesort(int array1[]);void diaplay(int a);};void list::input(int a){cout<<"Please input shorted array:"<<endl;for(int i=0;i<a;i++)cin>>array[i];}void list::merge(int arrayc[],int arrayd[],int l,int m,int r) {int i=l;int j=m+1;int k=l;while((i<=m)&&(j<=r))if(arrayc[i]<=arrayc[j])arrayd[k++]=arrayc[i++];else arrayd[k++]=arrayc[j++];if(i>m)for(int q=j;q<=r;q++)arrayd[k++]=arrayc[q];elsefor(int q=i;q<=m;q++)arrayd[k++]=arrayc[q];}void list::mergepass(int arrayx[],int arrayy[],int s){int i=0;while(i<=N-2*s){merge(arrayx,arrayy,i,i+s-1,i+2*s-1);i=i+2*s;}if((i+s)<N)merge(arrayx,arrayy,i,i+s-1,N-1);elsefor(int j=i;j<N;j++)arrayy[j]=arrayx[j];}void list::mergesort(int array1[]){int array2[N];int s=1;while(s<N){mergepass(array1,array2,s);s+=s;mergepass(array2,array1,s);s+=s;}}void list::diaplay(int a){for(int i=N-a;i<N;i++)cout<<array[i];}void main(){list f;int a;cout<<"请输入要合并排序的数组大小:(数组最大上限100)"<<endl;cin>>a;f.input(a);f.mergesort (f.array);f.diaplay (a);}合并排序:2#include <iostream>usingnamespace std;void MERGES(int *A,int p,int q,int r) //下标P<=q<r{int n1=q-p+1; //n1:p,q之间的数的个数int n2=r-q; //n2:q以后到r的数的个数int *L=newint [n1+1], //动态申请两个子数组*R=newint [n2+1];int i,j,k;for (i=0;i<n1;i++){L[i]=A[p+i-1];}for (j=0;j<n2;j++){R[j]=A[q+j];}L[n1]=10000; //设置哨兵R[n2]=10000;i=0;j=0;for (k=p-1;k<r;k++){if (L[i]<=R[j]){A[k]=L[i];i=i+1;}else{A[k]=R[j];j=j+1;}}}void MERGESORT(int *A,int p,int r) {if (p<r){int q=(p+r)/2;MERGESORT(A,p,q);MERGESORT(A,q+1,r);MERGES(A,p,q,r);}}void main(){int x,z,p,r;cout<<"请输入数组长度"<<endl;cin>>x;int *A= newint[x];cout<<"请输入数组的元素"<<endl;for(int y=0;y<x;y++){cin>>z;A[y]=z;}cout<<"请输入上下限p,r"<<endl;cin>>p>>r;MERGESORT(A,p,r);cout<<"合并排序后为:"<<endl;for (int m=p;m<=r;m++){cout<<A[m];}delete []A;}合并排序3:#include <iomanip.h>#include <iostream.h> //这个函数将b[0]至b[right-left+1]拷贝到a[left]至a[right] template <class T>void Copy(T a[],T b[],int left,int right){int size=right-left+1;for(int i=0;i<size;i++){a[left++]=b[i];}} //这个函数合并有序数组a[left:i],a[i+1:right]到b,得到新的有序数组b template <class T>void Merge(T a[],T b[],int left,int i,int right){int a1cout=left,//指向第一个数组开头a1end=i,//指向第一个数组结尾a2cout=i+1,//指向第二个数组开头a2end=right,//指向第二个数组结尾bcout=0;//指向b中的元素for(int j=0;j<right-left+1;j++)//执行right-left+1次循环{if(a1cout>a1end){b[bcout++]=a[a2cout++];continue;}//如果第一个数组结束,拷贝第二个数组的元素到bif(a2cout>a2end){b[bcout++]=a[a1cout++];continue;}//如果第二个数组结束,拷贝第一个数组的元素到bif(a[a1cout]<a[a2cout]){b[bcout++]=a[a1cout++];continue;}//如果两个数组都没结束,比较元素大小,把较小的放入belse{b[bcout++]=a[a2cout++];continue;}}} //对数组a[left:right]进行合并排序template <class T>void MergeSort(T a[],int left,int right){T *b=new int[right-left+1];if(left<right){int i=(left+right)/2;//取中点MergeSort(a,left,i);//左半边进行合并排序MergeSort(a,i+1,right);//右半边进行合并排序Merge(a,b,left,i,right);//左右合并到b中Copy(a,b,left,right);//从b拷贝回来}} //from /zhangamxqunint main(){int n;cout<<"how many numbers to sort:";cin>>n;int *a=new int[n];cout<<"input "<<n<<" numbers:";for(int i=0;i<n;i++){cin>>a[i];}MergeSort( a, 0, n-1);for(int j=0;j<n;j++){cout<<setw(5)<<a[j];}return 1;}合并排序4:#include <iostream>using namespace std;void Merge(int a[],int b[],int l,int m,int r) {int i=l,j=m+1,k=l;while ((i<=m)&&(j<=r))if (a[i]<=a[j])b[k++]=a[i++];else b[k++]=a[j++];if (i>m)for(int q=j;q<=r;q++)b[k++]=a[q];elsefor(int q=i;q<=m;q++)b[k++]=a[q];}void Copy(int a[],int b[],int s,int n){for(int i=s;i<=n;i++)a[i]=b[i];}void MergeSort(int a[],int left,int right) {int i;if(left<right){i=(left+right)/2;int b[100];MergeSort(a,left,i);MergeSort(a,i+1,right);Merge(a,b,left,i,right);Copy(a,b,left,right);}}int main(){int a[100];int n,i;cout<<"输入元素个数n:";cin>>n;cout<<"输入一维数组a["<<n<<"]:";for( i=0;i<n;i++)cin>>a[i];MergeSort(a,0,n-1);cout<<"输出排序为:";for ( i=0;i<n;i++)cout<<a[i]<<' ';cout<<endl;return 0;}矩阵相乘1:#include <iostream>#include <stdio.h>using namespace std;int main(){int i, j, k;cout<<"输入二维数组a的行数和二维数组c的行数x:";int x;cin>>x;cout<<"输入二维数组a的列数和二维数组b的行数y:";int y;cin>>y;cout<<"输入二维数组b的列数和二维数组c的行数z:";int z;cin>>z;int **a, **b, **c;a=new int*[x];for(i=0;i<x;i++){a[i]=new int[y];}cout<<"输入二维数组a:"<<endl;for(i=0;i<x;i++){for(j=0;j<y;j++){cin>>a[i][j];}}b=new int*[y];for(i=0;i<y;i++){b[i]=new int [z];}cout<<"输入二维数组b:"<<endl;for(i=0;i<y;i++){for(j=0;j<z;j++){cin>>b[i][j];}}c=new int*[x];for(i=0;i<x;i++){c[i]=new int [z];}cout<<"输入二维数组c:"<<endl;for(i=0;i<x;i++){for(j=0;j<z;j++){c[i][j]=0;}}for(i=0;i<x;i++){for(j=0;j<z;j++){for(k=0;k<y;k++){c[i][j]+=a[i][k]*b[k][j];}}}for(i=0;i<x;i++){for(j=0;j<z;j++){cout<<c[i][j]<<' ';}cout<<endl;}for(i=0;i<x;i++){delete [] a[i];}delete [] a;for(i=0;i<x;i++){delete [] c[i];}delete [] c;for(i=0;i<y;i++){delete [] b[i];}delete [] b;return 0;}矩阵相乘2:#include<iostream>using namespace std;#define M 2#define N 3#define P 4int main(){int a[M][N]={{1,2,3},{4,5,6}};int b[N][P]={{7,8,9,1},{2,3,4,5},{6,7,8,9}};int c[M][P];int i,j,k;for(i=0;i<M;i++)for(j=0;j<P;j++)c[i][j]=0;for(i=0;i<M;i++)for(j=0;j<P;j++)for(k=0;k<N;k++)c[i][j]+=a[i][k]*b[k][j];cout<<"矩阵相乘结果是:"<<endl;for(i=0;i<M;i++){for(j=0;j<P;j++)cout<<c[i][j]<<" ";cout<<endl;}//system("pause");return 0;}矩阵相乘3:#include <iostream>#include <iomanip>using namespace std;int main(){const int m=3;const int n=3;int a[m][n],i,j; //初始化数组a,bfor(i=0;i<m;i++) //对数组 a 赋值并显示{for( j=0;j<n;j++){cout<<"a["<<i<<"]"<<"["<<j<<"]=";cin>>a[i][j];}}for( i=0;i<m;i++){for( j=0;j<n;j++)cout<<setw(4)<<a[i][j];cout<<endl;}const int k=3;const int h=2;int b[k][h],x,y;for( x=0;x<k;x++){for( y=0;y<h;y++){cout<<"b["<<x<<"]"<<"["<<y<<"]=";cin>>b[x][y];}}for( x=0;x<k;x++){for( y=0;y<h;y++)cout<<setw(4)<<b[x][y];cout<<endl;}int c[m][h]; //乘赋值给数组cfor(int r=0;r<m;r++){for(int t=0;t<h;t++) //数组a 与b 相//对数组b 赋值并显示{c[r][t]=0;for(int s=0;s<k;s++){c[r][t]+=a[r][s]*b[s][t];}}}cout<<"c["<<m<<"]"<<"["<<h<<"]"<<endl;for(int z=0;z<m;z++){for(int w=0;w<h;w++)cout<<setw(4)<<c[z][w];cout<<endl;}return 0; //显示数组c}矩阵相乘4:#include<iostream>using namespace std;void chain(int*p,int n,int m[][7],int s[][7])//p维数数组,m最优乘次数组,s记录划分方案{int j;for(int i=1;i<=n;i++)m[i][i]=0;for(int r=2;r<=n;r++){for(i=1;i<=n-r+1;i++){j=i+r-1;m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];s[i][j]=i;for(int k=i+1;k<j;k++){int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];if(t<m[i][j]){m[i][j]=t;s[i][j]=k;}}}}for(i=1;i<=n;i++)//我把它翻过来输出。
计算机算法设计与分析第三版华中科技大学课程设计

计算机算法设计与分析第三版华中科技大学课程设计简介计算机算法设计与分析是一门重要的计算机科学基础课程,旨在帮助学生掌握算法设计与分析的基本方法和技巧,以及能力和素养。
本文档主要介绍华中科技大学计算机学院关于计算机算法设计与分析第三版的课程设计。
设计目的与意义在计算机科学与技术领域中,算法设计与分析是必不可少的技能。
本次课程设计旨在帮助学生更好地掌握这一技能,培养其解决实际问题的能力和创新思维。
具体来说,本课程设计的目的和意义包括:1.培养学生掌握算法设计和分析的基本方法和原理。
2.帮助学生掌握基本数据结构和算法的实现。
3.促进学生通过实践掌握各种算法的实际应用。
4.加强学生的团队合作能力和创新意识。
设计内容本次课程设计的主要内容是设计和实现一个算法,要求学生通过小组协作完成。
具体要求如下:1.组成1-3人的小组;2.自主设计一个算法,注意必须是创新性的,并要求主体思路清晰、关键步骤明确、正确性可靠;3.在算法设计的过程中体会算法分析的重要性,在实现过程中体现时间与空间复杂度的控制;4.设计并实现一个可以泛用的软件程序,用于演示各种数据集的实现过程和结果输出等;5.材料、可以的软件程序都可以参考课堂提供的学习资料,但需要体现出数学计算、算法分析的过程和结论,要求学生在合理使用资料的前提下,自主思考和解决问题。
设计流程设计流程如下:第一阶段:确定算法在本阶段,学生应该自主思考和讨论,确定一个合适的算法,并撰写算法设计文档。
可以参考课堂上相关的算法设计和分析内容,同时根据自己的思考和理解,结合实际应用场景,设计一种创新性的算法。
第二阶段:算法实现在本阶段,学生应该根据算法设计文档,完成软件程序的实现。
需要注意的是,在实现过程中,要注重时间复杂度和空间复杂度的控制,并进行相应的测试和优化。
第三阶段:数据测试在本阶段,学生应该使用不同的数据集对已实现的算法进行测试,并进行相应的测试结果分析和总结。
同时,要考虑对应不同场景的应用性能和效果。
《计算机算法设计与分析》课程设计

《计算机算法设计与分析》课程设计用分治法解决快速排序问题及用动态规划法解决最优二叉搜索树问题及用回溯法解决图的着色问题一、课程设计目的:《计算机算法设计与分析》这门课程是一门实践性非常强的课程,要求我们能够将所学的算法应用到实际中,灵活解决实际问题。
通过这次课程设计,能够培养我们独立思考、综合分析与动手的能力,并能加深对课堂所学理论和概念的理解,可以训练我们算法设计的思维和培养算法的分析能力。
二、课程设计内容:1、分治法:(2)快速排序;2、动态规划:(4)最优二叉搜索树;3、回溯法:(2)图的着色。
三、概要设计:分治法—快速排序:分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。
递归地解这些子问题,然后将各个子问题的解合并得到原问题的解。
分治法的条件:(1) 该问题的规模缩小到一定的程度就可以容易地解决;(2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;(3) 利用该问题分解出的子问题的解可以合并为该问题的解;(4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
抽象的讲,分治法有两个重要步骤:(1)将问题拆开;(2)将答案合并;动态规划—最优二叉搜索树:动态规划的基本思想是将问题分解为若干个小问题,解子问题,然后从子问题得到原问题的解。
设计动态规划法的步骤:(1)找出最优解的性质,并刻画其结构特征;(2)递归地定义最优值(写出动态规划方程);(3)以自底向上的方式计算出最优值;(4)根据计算最优值时得到的信息,构造一个最优解。
●回溯法—图的着色回溯法的基本思想是确定了解空间的组织结构后,回溯法就是从开始节点(根结点)出发,以深度优先的方式搜索整个解空间。
这个开始节点就成为一个活结点,同时也成为当前的扩展结点。
在当前的扩展结点处,搜索向纵深方向移至一个新结点。
这个新结点就成为一个新的或节点,并成为当前扩展结点。
算法分析与设计教学大纲

算法分析与设计教学大纲一、课程概述二、预修条件1.数据结构基础知识。
2.编程语言基础。
三、授课目标1.掌握算法分析的基本方法和工具。
2.理解常见算法的设计思想和实现技巧。
3.能够独立设计、实现和优化算法解决实际问题。
四、教学内容1.算法基础知识(1)算法的概念和分类(2)算法分析的基本概念和方法(3)复杂度分析(4)递归与递归算法(5)分治法与减治法2.基本算法设计(1)贪心算法(2)动态规划算法(3)回溯算法3.高级算法设计(1)图算法:最短路径、最小生成树等(2)网络流算法:最大流、最小割等(4)近似算法:近似算法的基本思想与应用4.数据结构与算法分析(1)线性表和链表(2)栈和队列(3)树和二叉树(4)图和图的遍历算法五、教学方法1.理论课讲授:通过教师讲解、演示和示范等方式,让学生掌握算法基本知识和分析方法。
2.实践教学:通过课程设计和编程实践,让学生动手实践算法设计与实现,并对其进行分析和优化。
3.讨论与交流:组织学生进行小组讨论和互动交流,培养学生的合作学习能力和问题解决能力。
六、教学评估1.平时成绩:考察学生的课堂参与、作业完成情况和实验报告质量。
2.期中考试:考察学生对课程内容的掌握和理解。
3.期末考试:考察学生对课程内容的整体把握和综合应用能力。
七、参考教材1. 算法导论(第3版)- Thomas H. Cormen等2. 算法设计与分析基础(第4版)- Levitin A. V.八、教学资源1.电子课件和习题集。
2.在线编程平台和算法分析工具。
九、教学进度安排1.第1-2周:算法基础知识2.第3-5周:基本算法设计3.第6-8周:高级算法设计4.第9-11周:数据结构与算法分析5.第12-14周:综合应用与实践6.第15周:复习与总结备注:以上为算法分析与设计教学大纲的基本框架和内容,具体教学安排和进度可根据实际情况进行调整补充。
11算法设计与分析课程设计题目

算法设计与分析课程设计题目以下题目任选一题。
一、使用C、C++、C#或JAVA 语言设计相关算法并编写一个完整的程序,计算任意两个整数a,b 的最大公因数,其中0≤a,b≤10100。
(要求:禁止网上下载大数类实现;10 分钟内输出结果)二、使用C、C++、C#或JAVA 语言设计相关算法并编写一个简单的中国象棋模拟程序。
三、地图着色问题。
对美国地图进行着色,两个共同边界的州着不同的颜色,当可以选择7、6、5、4种不同的颜色的情况下,由程序自动进行处理,给出具体的着色方案。
四、罗密欧与朱丽叶的迷宫问题。
罗密欧与朱丽叶身处一个m×n的迷宫中,如图所示。
每一个方格表示迷宫中的一个房间。
这m×n个房间中有一些房间是封闭的,不允许任何人进入。
在迷宫中任何位置均可沿8 个方向进入未封闭的房间。
罗密欧位于迷宫的(p,q)方格中,他必须找出一条通向朱丽叶所在的(r,s)方格的路。
在抵达朱丽叶之前,他必须走遍所有未封闭的房间各一次,而且要使到达朱丽叶的转弯次数为最少。
每改变一次前进方向算作转弯一次。
请设计和实现一个算法帮助罗密欧找出这样一条道路。
五、宝石游戏:宝石游戏比较有趣,它在13X6 的格子里进行。
游戏给出红色、蓝色、黄色、橘黄色、绿色、和柴色的宝石。
当任何三个以上宝石具有相同颜色并且在一条直线(横竖斜)时,这些宝石可以消去。
游戏如图所示。
现在给定当前游戏状态和一组新的石头,请编程计算当所有石头落下时游戏的状态。
提示:输入:第一行n 表示n 组测试数据。
下面每一个测试数据包含一个13X 6 的字符表,其中B 表示蓝色,R 表示红色,O 表示橘黄色、Y 表示黄色,G 表示绿色,P 表示紫色,W 表示此处没有宝石。
接下来三行,每行包含一个字符,表示新来的宝石下落的位置。
输出:每一个测试样例,输出当所有宝石落下后游戏的状态。
样例输入:1WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWBBWWWWBBWWWWOOWWWWBBY3样例输出:WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWOOYWWW六、若部分同学做以上五题均有难度,经指导老师同意可实现教材上任意三个经典算法。
算法设计与分析课程设计报告(五子棋).doc

算法设计与分析课程设计报告(五子棋)西安工业大学计算机科学与工程学院算法设计与分析课程设计题目五子棋班级050606 人数13人成员陈玮高谦侯夕杰马涛宋文彬王伟周仁文邵文清赵瑞红李盈超尉建明陈建军张祥雄学号050606102 050606105 050606108 050606114 050606117 050606120 050606126 050606129 050606132 040609111 040606123 050606101 040610127 时间2008年元月16日班级050606 学号题目五子棋完成时间1月16日指导教师杨国梁、陈芳小组排名邵文清,赵瑞红,李盈超,尉建明,周仁文,侯夕杰,陈建军,张祥雄陈玮,宋文彬,高谦,马涛,王伟小组成绩个人得分第1名邵文清赵瑞红贡献细节设计,完成void draw_box;void change;void judgekey的设计并完成实验报告第2名李盈超尉建明贡献主要负责程序的整体规划,完成主函数的设及相关变量的定义,完成void attentoin的设计第3名周仁文侯夕杰贡献完成void judgewhoint x,int y的设计第4名陈建军张祥雄贡献完成void draw_cicleint x,int y,int color的设计第5名陈玮宋文彬贡献完成int judgeresultint x,int y的设计第6名高谦,马涛王伟贡献调试并运行程序备注考核标准1. 个人文档资料40 2. 软件验收40 3. 考勤20 目录1课程设计报告-------------------31.1问题描述----------------------3 1.2需求分析---------------------------3 1.3概要设计-----------------------3 1.4详细设计-----------------------5 1.5调试分析---------------------6 2源程序---------------------6 3程序的说明文件-------------------13 4课设总结-----------------------13 1. 课程设计报告1.1问题描述连珠五子棋是有两个人在一盘棋上进行对抗的竞技运动。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法设计与分析论文学院:计算机科学与技术专业:计算机11-2姓名:席世权学号:3111090102252.简述动态规划算法求解问题的一般步骤。
答:(1)分析找出最优解的性质,并刻画其结构特征。
(2)递归地定义最优值。
(3)以自底向上的方式或自顶向下的记忆化方法(备忘录法)计算出最优值。
(4)根据计算最优值时得到的信息,构造一个最优解3.简述什么是备忘录方法。
答:备忘录方法是动态规划算法的变形。
与动态规划算法一样,备忘录方法用表格保存已经解决的子问题的答案,在下次需要解此子问题时,只要简单地查看该子问题的解答,而不必重新计算。
与动态规划算法不同的是,备忘录方法的递归方式是自顶向下的,而动态规划算法则是自底向上递归的。
因此,备忘录方法的控制结构与直接递归方法的控制结构相同,区别在于备忘录方法为每个解过的子问题建立了备忘录以备需要时查看,避免了相同子问题的重复求解。
2、给定n 种物品和一背包。
物品i 的重量是wi ,其价值为vi ,背包的容量为C 。
问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大?要求对每种物品i 装入背包或不装入背包。
不能将物品i 装入背包多次,也不能只装入部分的物品i (要求使用递归法实现)。
答:1、算法分析根据问题,可知此问题的形式化描述是,给定C>0,wi>0,vi>0,1≤i ≤n ,要求找出n 元0-1向量(x1,x2,…,xn),xi ∈{0,1},1≤i ≤n ,使得C x w ni i i ∑=≤1,而且∑=ni i i x v 1达到最大。
因此,0-1背包问题是一个特殊的整数规划问题。
可以用数学公式表达为:⎪⎩⎪⎨⎧≤≤∈≤∑=)1(},1,0{1n i x C x w ini i i 公式(1) ∑=ni i i x v 1max 公式(2)由上面的公式,可以将问题转换为:在满足公式(1)的条件下求解公式(2)达到最大时向量),......,,,(321n x x x x X =。
0-1背包问题最优子结构性质:0-1背包问题具有最优子结构性质。
设),......,,,(321n y y y y 是所给0-1背包问题的一个最优解,则),......,,(32n y y y 是下面相应子问题的一个最优解:∑∑==⎪⎩⎪⎨⎧≤≤∈-≤ni ii i ni i i x v n i x y w C x w 2211max )2(},1,0{。
如果不是的话,设),......,,(32n z z z 是上述子问题的一个最优解,而),......,,(32n y y y 不是,由此可知,∑∑==>n i n i i i i i y v z v 22,且∑=≤+n i i i C z w y w 211。
因此,∑∑∑====+>+ni i i n i ni i i i i y v y v y v z v y v 1221111∑=≤+n i i i C z w y w 211这说明向量),........,,,(321n z z z y 是所给的0-1背包问题的更优解,而),........,,,(321n y y y y 不是所给0-1背包问题的最优解。
此为矛盾。
递归分析:设所给0-1背包问题的子问题⎪⎩⎪⎨⎧≤≤∈≤∑∑==)1(},1,0{max 11i k x j x w x v ki k k k ik kk 的最优值为递归函数),(j i knapsack ,即该函数最终返回值是背包容量为j ,可选择物品为1,2,...,i 时0-1背包问题的最优值。
我们必须明白递归算法的思想是:把问题转化为规模缩小了的同类问题的子问题。
所以利用递归方法解决0-1背包问题,我们应该先从第n 个物品看起。
每次的递归调用都会判断两种情况装入或不装入:① 如果背包能放下第n 个物品,且放入第n 个物品的总价值大于不放入第n 个物品的总价值。
放入则x[n]=1,并继续递归调用背包容量为C-w[n],物品数目为n-1的递归函数,并返回此递归函数值与v[n]的和作为背包问题的最优解;② 如果背包放不下第n 个物品,则x[n]=0,并继续递归调用背包容量为C ,物品数目为n-1的递归函数,并返回此递归函数值作为背包问题的最优解。
递归调用的终结条件是,物品的数量为0,此时就得到了0-1背包问题的最优解, 就是knapsack(n,C)的返回值。
用递归法解0-1背包问题可以建立如下计算),(C n knapsack的递归式: ⎩⎨⎧+---=][])[,1(),1(),(n v n w C n knapsack C n knapsack C n knapsack n n 选择了物品没有选择物品 第一个式子表示不选择物品n 后得到的总价值),1(C n knapsack-不小于选择物品n 得到的总价值][])[,1(n v n w C n knapsack+--,所以最终不选择物品n;第二个式子刚好相反,选择物品n 后的总价值][])[,1(n v n w C n knapsack+--大于不选择物品n 情况下得到了总价值),1(C n knapsack-,所以最终选择物品n 。
在函数中,递归调用的主体函数为knapsack(n,C),参数C 表示背包的容量,n 表示物品的数量,x[n]表示是否选择了第n 个物品x[n]=1表示选择,x[n]=0表示没有选择。
2、程序实现基于以上讨论,可以设计解0-1背包问题的递归算法knapsack如下:int knapsack(int n,int C) //n表示物品的总个数;C表示背包的容量{if (n==0) //物品个数为0时直接返回0{return 0;}else if((C>=w[n])&&(knapsack(n-1,C)<(knapsack(n-1,C-w[n])+v[n]))) {x[n]=1; //装入物品nreturn knapsack(n-1,C-w[n])+v[n];}else{x[n]=0; //没有装入物品nreturn knapsack(n-1,C);}}3、计算复杂性分析int knapsack(int n,int C)函数的复杂性比较复杂,它与参数n,C都有关系。
整体分析,从程序的源代码中,可以得出需要O(nC)计算时间。
4、通过简例说明程序实现过程简例:设物品个数n为2,背包容量为2;重量分别为1,2,价值分别为2,4。
实现过程:第一步:调用knapsack(2,2)传入参数n=2,C=2;判断因为n!=0且C>=w[2],所以执行knapsack(1,2)<knapsack(1,2-w[2])+v[2]。
第二步:进入knapsack(1,2),此时n=1,判断因为n!=0且C>=w[1],所以执行knapsack(0,2)<knapsack(0,2-w[1])+v[1]。
进入knapsack(0,2),此时n=0,判断因为n等于0所以返回0,进入knapsack(0,2-w[1])同样返回0,因为0<0+v[1],所以knapsack(1,2)最终返回v[1],且x[1]=1。
第三步:进入knapsack(1,2-w[2]),此时C=0,判断n!=0,但是C<w[1],所以返回knapsack(0,0)即返回0,且x[1]=0。
第四步:回到第一步可知knapsack(1,2)<knapsack(1,2-w[2])+v[2]条件成立,所以knapsack(2,2)返回knapsack(1,2-w[2])+v[2]即返回v[2],且x[2]=1。
综上得:最优解为4,x[1]=0,x[2]=1。
5、源代码#include<stdio.h>#define N 60 //定义物品最大个数为60int w[N]; //数组,用于存放每个物品的质量int v[N]; //数组,用于存放每个物品的价值int x[N]; //数组,用于存放选择背包的结果int knapsack(int n,int C) //n表示物品的总个数;C表示背包的容量{if (n==0) //物品个数为0时直接返回0{return 0;}else if((C>=w[n])&&(knapsack(n-1,C)<(knapsack(n-1,C-w[n])+v[n]))) {x[n]=1; //装入物品nreturn knapsack(n-1,C-w[n])+v[n];}else{x[n]=0; //没有装入物品nreturn knapsack(n-1,C);}}void main(){int C,n;int i=0,j=0;system("color A");printf("\t\t\t0-1背包问题递归算法实例运行\n\n");printf("请输入物品个数n,背包容量C,之间用空格隔开\n");scanf("%d%d",&n,&C);printf("请分别输入每个物品的重量w,物品的价值v,之间用空格隔开\n");for(i=1;i<=n;i++)scanf("%d%d",&w[i],&v[i]); //分别输入重量w,价值v printf("\t***********************输出结果***************************\n\n") ;for(i=0;i<=C;i++){printf("背包容量为: %d\t最优解为: %d\t选择的背包为: ",i,knapsack(n,i));for(j=1;j<=n;j++)printf("x[%d]=%d ",j,x[j]); //输出选择背包的结果printf("\n");}}程序运行结果截图:图1 0-1背包问题递归算法实力运行图5、100元的具体划分方案,可选面值有1元、10元、20元、50元、100元。
答:1、算法分析问题提出:100元的具体划分方案,无需输入,但要求输出总的划分方案数,和每次方案的具体划分情况。
根据问题,可知此问题非常适合用递归算法,因为递归算法的思想是:把问题转化为规模缩小了的同类问题的子问题。
该题问题就是大划分为小。
具体分析此题,由于要输出总的划分方案数,所以要定义一个全局变量,int count = 0;由于要输出每次方案的具体划分,所以要定义一个整数数组,但是数组要多大?分析此题最多划分数为100张1元的,则定义数组为int a[100] = {0};为了分别取出可选面值,再定义一个整数数组存放所给可选面值,int b[5] = {100,50,20,10,1}。