算法4_分治

本文探讨了分治法在算法设计中的应用,包括选择问题的解决方案和输油管道问题的最优位置确定。介绍了快速排序算法及其在选择问题中的应用,并提供了一个计算输油管道最小长度总和的实例。

概述

根据分治法的分割原则,原问题应该分为多少个子问题才较适宜?各个子问题的规模应该怎样才为适当?这些问题很难予以肯定的回答。
在用分治法设计算法时,最好使子问题的规模大致相同。如分成大小相等的k个子问题,许多问题可以取k=2。
这种使子问题规模大致相等的做法是出自一种平衡(Balancing)子问题的思想,它几乎总是比子问题规模不等的做法要好。
适用条件
分治法所能解决的问题一般具有以下几个特征:

1.该问题的规模缩小到一定的程度就可以容易地解决;
2.该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;
3.利用该问题分解出的子问题的解可以合并为该问题的解;
4.该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。

选择问题

对于给定的n个元素的数组a[0:n—1],要求从中找出第k小的元素。
输入
输入有多组测试例。
对每一个测试例有2行,第一行是整数n和k(1≤k<n≤1000),第二行是n个整数。
输出
第k小的元素。
算法分析:
一种简单的解决方法就是对全部数据进行排序,于是得到问题的解。
快速排序算法是分治策略的典型应用,不过不是对问题进行等份分解(二分法),而是通过分界数据(支点)将问题分解成独立的子问题。
首先选第一个数作为分界数据,将比它小的数据存储在它的左边,比它大的数据存储在它的右边,它存储在左、右两个子集之间。这样左、右子集就是原问题分解后的独立子问题。
再用同样的方法,继续解决这些子问题,直到每个子集只有一个数据,就完成了全部数据的排序工作。
利用快速排序算法的思想,来解决选择问题。
记一趟快速排序后,分解出左子集中元素个数为 nleft,则选择问题可能是以下几种情况之一:
nleft =k﹣1,则分界数据就是选择问题的答案。
nleft >k﹣1,则选择问题的答案继续在左子集中找,问题规模变小了。
nleft <k﹣1,则选择问题的答案继续在右子集中找,问题变为选择第k-nleft-1 小的数,问题的规模变小了。

int select (int left,int right,int k)
{
	if (left >= right) return a [left] ;
	int i = left;	
	int j = right+1;	
	int pivot = a[left];
	while (true){
		do {
			i= 1+1;
		} while (a[i] < pivot) ;
		do {
			j=j-1;
		} while (a[j] > pivot) ;
		if(i>=j)break;	
				swap(a[i],a[j]) ;
	}
	if (-1eft+1 == k) return pivot;
	a[left] = a[j];		
	a[j] = pivot;
	if (j-left+1 < k)
	return select (j+1,right, k-j+1eft-1) ;
	else return select(1eft, j-1, k) ;
}

输油管道问题

某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有n口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。
如果给定n口油井的位置,即它们的x坐标(东西向)和y坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管道长度总和最小的位置?
给定n口油井的位置,编程计算各油井到主管道之间的输油管道最小长度总和。

输入
第1行是一个整数n,表示油井的数量(1≤n≤10 000)。
接下来n行是油井的位置,每行两个整数x和y
(﹣10 000≤x,y≤10 000)。
输出
各油井到主管道之间的输油管道最小长度总和。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,x,a[10001],min=0;
    cin>>n;
    for(int k=0;k<n;k++){
        cin>>x>>a[k];
    }
    sort(a,a+n);
    for(int i=0;i<n;i++){
        min=min+(int)fabs(a[i]-a[n/2]);
    }
    cout<<min<<endl;
    return 0;
}

快速排序

基本思想:
• 用首元素 x 作划分标准,将输入数 组 A划分成不超过 x 的元素构成的数 组 AL,大于 x 的元素构成的数组 AR. 其中 AL, AR从左到右存放在数组 A
的位置.
• 递归地对子问题 AL和 AR 进行排序, 直到子问题规模为 1 时停止.
伪码
算法 Quicksort (A, p, r)
输入:数组A[p…r]
输出:排好序的数组 A
if p < r
then q<-Partition (A, p, r)
A[p]<->A[q]
Quicksort (A, p, q-1)
Quicksort (A, q+1, r)
初始置 p=1, r=n,然后调用上述算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值