分治入门与实例(南昌理工学院ACM集训队)

本文介绍了分治算法的基本特征,包括平衡子问题和独立子问题,并通过归并排序作为入门示例进行详细解析。接着,文章探讨了如何使用分治法解决HDU 4911的最小逆序对问题,以及在平面最近点对问题上的应用,强调了在处理这类问题时避免暴力方法的重要性,提出了有效的优化策略。
摘要由CSDN通过智能技术生成

分治问题特征

(1)平衡子问题:子问题规模大致相同,能把问题划分成大小差不多相等的k个子问题,最好k=2,即分成两个规模相等的子问题。子问题规模相等的处理效率比子问题不等的效率要高
(2)独立子问题 :子问题之间相互独立。这是区别于动态规划算法的基本特征,动态规划算法中子问题是相互联系,不是相互独立的。

特别需要说明的是,分治法不仅能让问题变得容易理解和解决,而且能大大优化算法的复杂度,一般能把O(N)优化到O(log2n)。

这是因为局部的优化有利于全局;
一个子问题的解决,其影响力扩大了k倍,即扩大到了全局

入门:归并排序

归并排序步骤
(1)分解:把原来无序的数列分成两部分,对每个部分,再继续分成更小的两部分

这个过程用递归实现

(2)解决:分解到最后不能再分解,排序

对子序列排序。最低层子序列只包含一个数,不用排序

(3)合并:把每次分开的两部分合并到一起。归并排序的核心操作是合并,其过程类似于交换排序。

而排序一般用stl的sort()排序,不过有些特殊问题可以用归并排序解决

HDU 4911(求最小逆序对).
分析
当k=0时,就是求原始序列中有多少个逆序对
求k=0时的逆序对,不能用暴力法,会TLE
可以用归并思想来解决

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include <vector>
using namespace std;

const int MAXN = 100005;
typedef long long ll;
ll a[MAXN], b[MAXN], cnt;

void Merge(ll l, ll mid, ll r) {
   //合并函数
	ll i = 1, j = mid + 1, t = 0;
	while (i <= mid && j <= r) {
   
		if (a[i] > a[j]) {
   
			b[t++] = a[t++];
			cnt += mid - i + 1;//记录逆序对的数目
		}
		else b[t++] = a[i++];
	}
	//一个子序列中的数据都处理完了,另一个还没有,把剩下的复制过来
	while (i <= mid)b[t++] = a[t++];
	while (j 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值