其他分享
首页 > 其他分享> > 分治思想总结

分治思想总结

作者:互联网

日期:2022年5月18日

注:本博客仅供参考


 

概念与基本思路

分治,即“分而治之”,就是把一个复杂的问题分解成两个或更多个相同或相似的子问题,一直分解到子问题可以简单地直接求解,原问题的解即为子问题的解的合并。

应用

分治是很多高效算法的基础,如快速排序、归并排序(虽然在sort函数的帮助下,已无自己写排序算法的必要,但其思想依然值得去学习与应用)等等。

实现方法

可以使用递归将大问题逐步分割为一个个元素,再在每一个元素中将问题解决并将元素逐步合并,最后就能得到大问题的答案。

代码

归并排序(P1177)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[100100],t[100100];
 4 void mergeSort(int L,int R){
 5     if(L==R)//当问题已经分解为一个个元素时不再分解
 6     {
 7         return;
 8     }
 9     int mid=(L+R)/2;//将问题一分为二
10     mergeSort(L,mid);//左边的一半进行递归
11     mergeSort(mid+1,R);//右边的一半也进行递归
12     int i=L,j=mid+1;
13     for(int k=L;k<=R;++k)
14     {
15         if(j>R||i<=mid&&a[i]<=a[j])//右半边已经排完或左半边中某个元素大于右半边中某个元素
16         {
17             t[k]=a[i];//将更小的元素复制到一个暂时存储结果的文件夹
18             ++i;//比较左半边的下一个元素
19         }else{//左半边已经排完或右半边某个元素大于左半边某个元素
20             t[k]=a[j];//同理,复制更小的元素
21             ++j;//同理,比较右半边的下一个元素
22         }
23 
24     }
25     for(int k=L;k<=R;++k)
26     {
27         a[k]=t[k];//将排好的元素还原到原来数组中(因为还需要和数组的其他部分进行排序)
28     }
29 }
30 int main(){
31     scanf("%d",&n);
32     for(int i=1;i<=n;++i)
33     {
34         scanf("%d",&a[i]);
35     }
36     mergeSort(1,n);
37     for(int i=1;i<=n-1;++i)
38     {
39         printf("%d ",a[i]);
40     }
41     printf("%d\n",a[n]);
42     return 0;
43 }

逆序对(P1908,可以看作为归并排序的应用)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[500100],t[500100];
 4 long long ans=0;
 5 void mergeSort(int L,int R){
 6     if(L==R)
 7     {
 8         return;
 9     }
10     int mid=(L+R)/2;
11     mergeSort(L,mid);
12     mergeSort(mid+1,R);
13     int i=L,j=mid+1;
14     for(int k=L;k<=R;++k)
15     {
16         if(j>R||i<=mid&&a[i]<=a[j])
17         {
18             t[k]=a[i];
19             ++i;
20         }else{
21             t[k]=a[j];
22             ++j;
23             ans+=mid-i+1;//增加的部分
24         }
25 
26     }
27     for(int k=L;k<=R;++k)
28     {
29         a[k]=t[k];
30     }
31 }
32 int main(){
33     scanf("%d",&n);
34     for(int i=1;i<=n;++i)
35     {
36         scanf("%d",&a[i]);
37     }
38     mergeSort(1,n);
39     printf("%lld",ans);
40     return 0;
41 }

心得

标签:总结,mergeSort,思想,int,分治,mid,问题,排序
来源: https://www.cnblogs.com/PlayerSS05/p/16287834.html