- 1、本文档共15页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第二章:递归与分治策略 ---士兵站队问题 问题描述: 在一个划分成网格的操场上,n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表示。士兵们可以沿网格边上、下、左、右移动一步,但在同一时刻任一网格点上只能有一名士兵。按照军官的命令,士兵们要整齐地列成一个水平队列,即排列成(x,y),(x+1,y),…,(x+n-1,y)。如何选择x和y的值才能使士兵们以最少的总移动步数排成一列。 问题分析: 士兵有多种移动方式:通过适当的移动顺序和移动路线可以使得同一时刻不会有两名士兵站在同一点 题目要求最佳移动方式(即求移动的最少步数):转化为求士兵站立的“最终位置”,即如何取“最终位置”使得士兵移动的步数最少(最优)。 解题思路: Y轴方向上的考虑: 设目标坐标为M,即n个士兵最终需要移动到的Y轴的坐标值为M, n个士兵初始位置的Y轴坐标分别为:Y0,Y1,Y2…Yn-1 则最优步数S=|Y0-M|+|Y1-M|+|Y2-M|+…+|Yn-1-M|。 从最上和最下的两个士兵开始递推,可得M取中间点的值使得S为最少(最优),即处于中间位置的士兵的Y轴坐标值就是“最终位置”的Y轴坐标。 解决办法:对所有的Y轴坐标进行排序(O(nlogn))或者进行线性时间选择(O(n)),然后取“中间”点的Y轴坐标值作为最佳位置M的值,最后通过公式求出Y轴方向上移动的最优步数。 解题思路: X轴方向上的考虑 首先需要对所有士兵的X轴坐标值进行排序;然后,按从左至右的顺序依次移动到每个士兵所对应的“最终位置”,所移动的步数总和就是X轴方向上需要移动的步数。例,最左的士兵移动到“最终位置”的最左那位,第二个士兵移动到“最终位置”的第二位则总的步数为: 士兵1移动步数+士兵2移动步数+ …… +士兵n移动步数。 如何确定X轴方向上的最佳的“最终位置”? n个士兵他们相应的X轴坐标为:X0,X1,X2…Xn-1 设“最终位置”的X轴坐标值为:k,k+1,k+2…k+(n-1) 则最优步数:S=|X0-k|+|X1-(k+1)|+|X2-(k+2)|+…+|Xn-1-(k+(n-1))| 经过变形:S=|X0-k|+|(X1-1)-k|+|(X2-2)-k|+…+|(Xn-1-(n-1))-k| X轴方向公式的形式与Y轴方向上的考虑一样,同样是n个已知数分别减去一个待定数后取绝对值,然后求和。因此还是采用取中位数的办法求得k值,最后算出最优解。 算法实现: 1、用快速排序对士兵当前位置的x轴坐标进行排序 2、分别找出x轴坐标和y轴坐标的第(n+1)/2小元素,即中位数 3、分别算士兵当前位置的x轴和y轴坐标值到各自中位数的绝对差之和,最后把这两个值相加即为所求的最少步数。 #include iostream #include math.h #include stdlib.h using namespace std; void Swap(int a,int b)//交换函数 { int temp;//定义一个交换的临时变量 temp=a; a=b; b=temp; } int partition(int *a,int low,int high)//确定一个基准元素以对数组元素进行划分 { int key = a[low];//key初始化为a的首元素 while(lowhigh) { while(lowhigh a[high]=key) high--; a[low] = a[high]; while(lowhigh a[low]=key) low++; a[high]=a[low]; } a[low]=key; return low; } //在a[low:high]中随机选一个元素作为基准,以期划分较对称 int RandomizedPartition(int *a,int low,int high) { int i = rand()%(high-low+1)+low;//rand()函数可以生成一个随机数, Swap(a[i],a[low]);//将随机挑选的元素与数组首元素交换 return partition(a,low,high); } int RandomizedSelect(int *a,int p,int r,int k)//找数组中a[p:r]的第k小元素 { if(p == r) return a[p]; int i=RandomizedPartition(a,p,r);//将数
您可能关注的文档
最近下载
- 北京市海淀区七年级第一学期期末统考地理试卷-初一地理试卷与试题.pdf VIP
- 西南18J312-楼地面-踢脚-变形缝-涂料构造.pdf VIP
- 国际私法【机考真题】-0069.pdf
- 旋塞阀装配图的画图步骤抄画下图所示旋塞阀的装配图课件.pptx VIP
- 优秀传统文化进幼儿园的实践性研究开题、中期、结题报告.pptx VIP
- 2023年烟草公司半结构化面试实例及解析(一).pdf VIP
- 2023年湖南省长沙市(初三学业水平考试)中考物理真题试卷含详解.docx VIP
- 业务连续性管理实施指南.docx VIP
- 《民族大团结》ppt课件.pptx
- 2025至2030年中国粉煤灰综合利用行业发展趋势及投资前景预测报告.docx
文档评论(0)