ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

分治思想总结

2022-05-20 16:34:01  阅读:192  来源: 互联网

标签:总结 mergeSort 思想 int 分治 mid 问题 排序


日期: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 }

心得

  • 分治需要划定界限,否则会一直分下去而RE
  • 相比于分治,二分可能更简单一些(因为二分可以不用递归就能实现)
  • 也需要注意开的数能否承载下要承载的数据

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有