zoukankan      html  css  js  c++  java
  • 分治算法总结

    分治算法定义

    将一个问题分解成多个子问题,将问题缩小到一定规模后逐个求解,最后合并所有子问题

    分治算法步骤

    1. 分解(将原问题分解成一个形式相同规模更小的子问题)
    2. 解决(递归求解子问题,直到问题的规模足够小,直接求解)
    3. 合并(合并子问题的解,得到原问题的解)

    分治算法例题(实际应用)

    插入排序

    思路

    一道十分普通的(O(n^2))时间复杂度题,使用类似打扑克牌时给牌排序的分治思想递归实现即可

    即:

    先给n-1张牌排序,再分成给n-2张牌排序,以此类推.......

    直到只剩1张牌,则直接结束

    (Code)

    #include<bits/stdc++.h>
    using namespace std;
    int n,a[110];
    void insert_sort(int a[],int n){
    	//1.基本情况 
    	if(n==1)return;
    	//2.分解子问题 
    	//3.解决子问题 
    	insert_sort(a,n-1);
    	int tmp=a[n],i; 
    	for(i=n-1;i>=1;i--){
    		if(a[i]>tmp){
    			a[i+1]=a[i];
    		}else{
    			break;
    		}
    	}
    	a[i+1]=tmp;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	insert_sort(a,n);
    	for(int i=1;i<=n;i++){
    		printf("%d ",a[i]);
    	}
    	return 0;
    }
    

    归并排序

    思路

    这道题的数据范围加大,不能再用(O(n^2))算法解决,会导致TLE;故我们可以用归并排序解决

    图解

    (Code)

    #include<bits/stdc++.h>
    using namespace std;
    int n,a[110],b[110];
    void merge(int a[],int l,int mid,int r,int t[]){
    	int i=l,j=mid+1,k=l;
    	while(i<=mid&&j<=r){
    		if(a[i]<=a[j])t[k++]=a[i++];
    		else t[k++]=a[j++];
    	}
    	while(i<=mid)t[k++]=a[i++];
    	while(j<=r)t[k++]=a[j++];
    	for(i=l;i<=r;i++)a[i]=t[i];
    }
    void merge_sort(int a[],int l,int r,int t[]){
    	//1.基本情况 
    	if(l==r)return;
    	//2.分解子问题 
    	int mid=(l+r)>>1;
    	//3.解决子问题 
    	merge_sort(a,l,mid,t);
    	merge_sort(a,mid+1,r,t);
    	//4.合并子问题的解 
    	merge(a,l,mid,r,t);
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	merge_sort(a,1,n,b);
    	for(int i=1;i<=n;i++){
    		printf("%d ",a[i]);
    	}
    	return 0;
    }
    

    快速排序

    思路

    使用(O(n log n))时间复杂度的快速排序,具体步骤看下图

    (Code)

    #include<bits/stdc++.h>
    using namespace std;
    int n,a[100010];
    void quick_sort(int a[],int l,int r){
    	//1.基本情况 
    	if(l==r)return;//可省略
    	//2.分解子问题 
    	int i=l,j=r,mid=a[l+rand()%(r-l+1)];
    	while(i<=j){
    		while(a[i]<mid)i++;
    		while(a[j]>mid)j--;
    		if(i<=j){
    			swap(a[i],a[j]);
    			i++;
    			j--;
    		}
    	}
    	//3.解决子问题 
    	if(l<j)quick_sort(a,l,j);
    	if(i<r)quick_sort(a,i,r);
    	//4.合并子问题的解 
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	quick_sort(a,1,n);
    	for(int i=1;i<=n;i++){
    		printf("%d ",a[i]);
    	}
    	return 0;
    }
    
    她透过我的血,看到了另一抹殷红
  • 相关阅读:
    基础最短路(模板 bellman_ford)
    UVA-12304 Race(递推)
    How do you add?(递推)
    Coconuts, Revisited(递推+枚举+模拟)
    UVA-10726 Coco Monkey(递推)
    UVA-10995 Educational Journey
    UVA-10339 Watching Watches
    【React】377- 实现 React 中的状态自动保存
    【JS】376- Axios 使用指南
    【Nodejs】375- 如何加快 Node.js 应用的启动速度
  • 原文地址:https://www.cnblogs.com/zhangbeini/p/13617359.html
Copyright © 2011-2022 走看看