收藏 分享(赏)

算法设计与分析的一些实例分析.doc

上传人:dreamzhangning 文档编号:2305559 上传时间:2018-09-10 格式:DOC 页数:17 大小:91.50KB
下载 相关 举报
算法设计与分析的一些实例分析.doc_第1页
第1页 / 共17页
算法设计与分析的一些实例分析.doc_第2页
第2页 / 共17页
算法设计与分析的一些实例分析.doc_第3页
第3页 / 共17页
算法设计与分析的一些实例分析.doc_第4页
第4页 / 共17页
算法设计与分析的一些实例分析.doc_第5页
第5页 / 共17页
点击查看更多>>
资源描述

1、实验一 递归与分治策略一、实验目的:熟练掌握递归与分治策略的思想并应用其解决实际问题。二、递归与分治策略思想基本思想:将要求解的较大规模的问题分割成 k 个更小规模的子问题。对这 k 个子问题分别求解。如果子问题的规模仍然不够小,则再划分为 k 个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。实验题目(1-2):找出从自然数 1,2,,n 中任取 r 个数的所有组合。算法思想:当组合的第一个数字选定时,其后的数字是从余下的 m-1 个数中取 k-1 数的组合。这就将求 m 个数中取 k 个数的组合问题转化成求 m-1 个数中取 k-1 个数的组合问题。设函数引入工作数组

2、a 存放求出的组合,约定函数将确定的 k 个数字组合的第一个数字放在 ak中,当一个组合求出后,才将 a 中的一个组合输出。第一个数可以是 m、m-1、k,函数将确定组合的第一个数字放入数组后,有两种可能的选择,因还未确定组合的其余元素,继续递归去确定;或已确定了组合的全部元素,输出这个组合。问题描述:找出从自然数 1、2、n 中任取 r 个数的所有组合。例如 n=5,r=3 的所有组合为: (1)5、4、3 (2)5、4、2 (3)5、4、1 (4)5、3、2 (5)5、3、1 (6)5、2、1 (7)4、3、2 (8)4、3、1 (9)4、2、1 (10)3、2、1 分析所列的 10 个组

3、合,可以采用这样的递归思想来考虑求组合函数的算法。设函数为 void find(int m,int k)为找出从自然数 1、2、m 中任取 k 个数的所有组合。当组合的第一个数字选定时,其后的数字是从余下的 m-1 个数中取 k-1 数的组合。这就将求 m 个数中取k 个数的组合问题转化成求 m-1 个数中取 k-1 个数的组合问题。设函数引入工作数组 a 存放求出的组合的数字,约定函数将确定的 k 个数字组合的第一个数字放在 ak中,当一个组合求出后,才将 a 中的一个组合输出。第一个数可以是 m、m-1、k,函数将确定组合的第一个数字放入数组后,有两种可能的选择,因还未去顶组合的其余元素,

4、继续递归去确定;或因已确定了组合的全部元素,输出这个组合。细节见以下程序中的函数。 【程序】 #include #includeusing namespace std;#define MAXN 1000 int aMAXN; void f(int m,int k) int i,j; for(i=m;i=k;i-) ak=i; if(k1) f(i-1,k-1); else for(j=1;aj0;j+)printf(“%4d“,aj); printf(“n“); int main() int m,k,i;while(cinmk)for(i=0;iusing namespace std; #de

5、fine MAX 100 int num,aMAX=0; void Gray(int n) if(n1) Gray(n-1); if(an-1=0) an-1=1; else an-1=0; for(int i=0;i1) Gray(n-1); int main() int i; while(1)coutnum; for(i=0;iusing namespace std;#include #define N 1000 typedef struct int c,int d; Node; int n; /石头的堆数int vN; / 每堆石头的个数int saveN; / 输出最优解的 /具体合并

6、需要随时改变 v 的值,所以为了同时输出最小,最大的合并,在完成一个任务之后需要回溯 Node fNN; / fij存储最优解,同时存储合并线索 int sumNN; / sumij 表示从第 i 堆起,顺时针数 j 堆的石子总数 void Print(int i,int j) / 递归打印子序列 fij的合并过程 int k,x;if(j!=1) Print(i,fij.d); / 倒推子序列 1 的合并过程x=(i+fij.d-1)%n+1;Print(x,j-fij.d); / 倒推子序列 2 的合并过程 for(k=1;k0)if(i=k|x=k) printf(“-%d “,vk);

7、 / -号表示这次操作合并该堆 else printf(“%d “,vk); printf(“n“);vi=vi+vx; / 新堆的大小 vx=-vx; / 置为“-“ 类似于删除 void Solve(int flag) / flag = 0 求最小得分, flag = 1 求最大得分 int i,j,k,x,t,result;for(i=1;ifij.c) fij.c=fik.c+fxj-k.c+t;fij.d=k; result=f1n.c;k=1; / 在子序列 f1n, f2n.fnn中寻找最优值 for(i=2;iresult)result=fin.c;k=i; / 记录下 k p

8、rintf(“%s score is : %dn“,flag=0?“min“:“max“,result); printf(“合并过程如下:n“);coutn)则在当前加油站加满油,直到到达目的地;我们的算法必须保证既需要最少的加油次数,而且还必须能够到达目的地,且不能出现没有油并且还未到加油站的情况,因为这种情况势必造成油的浪费!算法流程图图 3-2 汽车加油程序流程图源代码:#includeusing namespace std;int main()int OilStationNum;/加油站的数目int MaxDist; /汽车加满油以后行驶的最大距离int DiscOfCar; /汽车一

9、次加油后已经行驶的距离int Count;int * OilStationDist;printf(“请输入加油站的段数(用整数表示):“);scanf(“%d“,printf(“汽车加满油以后行驶的最大距离(用整数表示):“);scanf(“%d“,OilStationDist=new int OilStationNum-1;printf(“请输入各各加油站之间的距离(假设不能有环路):n“);for(Count=0;CountOilStationNum)printf(“当前汽车到达终点,此时汽车距上一次加油行驶了%d 公里n“,DiscOfCar); break; return 0;运行结果

10、:请输入加油站的段数(用整数表示 ):3汽车加满油以后行驶的最大距离(用整数表示):50请输入各各加油站之间的距离(假设不能有环路):11 31 19当前汽车需要在 2 号加油站处加油,此时汽车行驶了 42 公里当前汽车到达终点,此时汽车距上一次加油行驶了 19 公里Press any key to continue2.6 二分覆盖问题二分图是一个无向图它的 n 个顶点可二分为集合 A 和 B,且同一集合中的任意两个顶点在图中无边相连,当且仅当 B 中的每个顶点至少与 A 中一个顶点相连时,A 的一个子集 A 覆盖集合 B,覆盖 A 的大小即为 A 中的顶点数目。当且仅当 A 是覆盖 B 的子

11、集时,A 为最小覆盖,在二分图中寻找最小覆盖的问题为二分覆盖问题。#include #include using namespace std;const int MAX_LEFT = 500;const int MAX_RIGHT = 500;class Bipartite private:struct Edge int to;Edge* next;Edge(int _to) to = _to;Edge* m_adjListMAX_LEFT;int m_lCnt;int m_rCnt;int m_lMatchRMAX_RIGHT;int m_rMatchLMAX_LEFT;int m_preL

12、MAX_LEFT;bool m_visitRMAX_RIGHT;bool m_matrixMAX_LEFTMAX_RIGHT;void clear() for (int i = 0; i next;delete pre;m_adjListi = NULL;memset(m_matrix, 0, sizeof(m_matrix);void findAugment(int start) for (int i = 0; i que;que.push_back(start);bool found = false;while (!que.empty() que.pop_front();Edge* edg

13、e = m_adjListfrom;while (edge != NULL if (!m_visitRto) m_visitRto = true;if (m_rMatchLto = -1) found = true;reverse(from, to);else que.push_back(m_rMatchLto);m_preLm_rMatchLto = from;edge = edge-next;void reverse(int left, int right) m_rMatchLright = left;while(m_preLleft != -1) int nextR = m_lMatch

14、Rleft;m_rMatchLnextR = m_preLleft;m_lMatchRleft = right;left = m_preLleft;right = nextR;m_lMatchRleft = right;public:Bipartite() memset(m_adjList, 0, sizeof(m_adjList);m_lCnt = 0;m_rCnt = 0;Bipartite() clear();void addEdge(int left, int right) if (!m_matrixleftright) m_matrixleftright = true;Edge* n

15、ewEdge = new Edge(right);newEdge-next = m_adjListleft; m_adjListleft = newEdge;int getLMatchR(int left) const return m_lMatchRleft;int getRMatchL(int right) const return m_rMatchLright;void init(int leftCnt, int rightCnt) clear();m_lCnt = leftCnt;m_rCnt = rightCnt;for (int i = 0; i int main() Bipart

16、ite match;match.init(300, 400);int a = 0, 0, 1, 1, 2, 2, 2;int b = 1, 2, 1, 3, 0, 1, 2;for (int i = 0; i using namespace std;#define N 100struct nodeint shape;int color;node aNN;int n;long num;bool bNN;void compute(int k)int i,j,i1,j1,i2,j2;if(k=n*n)/*列举出所有的情况,输出的 (i,j),其中:i 表示形状的类型 ,j 表示颜色的类型printf

17、(“n“);for(i=0;iusing namespace std;const int N=20;int a_xyN2;long sum;int n;void n_queue(int m)int i,j;if(m=n)/*printf(“the %ldth method:n“,sum+1);for(i=0;in;i+,printf(“n“)for(j=0;jn;j+)if(j=a_xyi1)printf(“* “);else printf(“0 “);for(i=0;in;i+)printf(“-“);printf(“n“);*/sum+;return ;bool t1;for(i=0;in

18、;i+)for(j=0,t1=true;jm;j+)if(a_xyj1=i|abs(a_xyj0-m)=abs(a_xyj1-i)t1=false;break;if(t1)a_xym0=m;a_xym1=i;n_queue(m+1);int main()while(true)printf(“please input n:“);scanf(“%d“,sum=0;n_queue(0);printf(“the result is:%ldn“,sum);return 0;运行结果:please input n:3the result is:0please input n:4the result is:2please input n:7the result is:40please input n:2the result is:0

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报