第二章作业
分治法
分治法,老师上课最常说的一个词就是分而治之;
分治法的基本思想:
分治法在书上的定义是将要求解的较大规模的问题分割成k个更小规模的子问题,
对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
分治法的三个步骤:(解题步骤类似)
① Divide(分解问题):把原问题分解成若干个余原问题性质相类似的子问题
② Conquer(求解子问题):不断分解子问题直到方便求出子问题的解为止
③ Combine(合并子问题)/(Merge):合并子问题的解得到原问题的解。
分治法适用的情况:
分治法所能解决的问题一般具有以下几个特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
3) 利用该问题分解出的子问题的解可以合并为该问题的解;
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;
第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;、
第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。
第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好
(参考博客:https://blog.csdn.net/effective_coder/article/details/8697789)
结对编程的报告
以课上的算法题为例子:
7-1 最大子列和问题 (20分)
给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:
- 数据1:与样例等价,测试基本正确性;
- 数据2:102个随机整数;
- 数据3:103个随机整数;
- 数据4:104个随机整数;
- 数据5:105个随机整数;
输入格式:
输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。
输出格式:
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
设计思想:
我个人的体会是:分治法光看概念以及听老师的讲解,有种高深莫测的感觉,但是应用起来的感觉很熟悉,有种我们生活中分类的感觉,分治法还可以应用在很多的方面,也许是现在接触的题目比较少,分治法在我的认知里面暂时还是分类讨论,希望随着认识的题目越多,对分治法有更深的认识。
代码:#include <iostream>
using namespace std;
int start (int a[],int left,int right){
int sum =0;
if(left==right){
if(a[left>=0]) sum=a[left];
else sum=0;
}
else{
int mid=(left+right)*0.5;
int leftnum=start(a,left,mid);
int rightnum=start(a,mid+1,right);
int r,g,tool;
r=tool=0;
for(int i=mid;i>=left;i--){
tool=tool+a[i];
if(tool>=r) r=tool;
}
g=tool=0;
for(int j=mid+1;j<=right;j++){
tool=tool+a[j];
if(tool>=g) g=tool;
}
sum=r+g;
if(leftnum>=sum) sum=leftnum;
if(rightnum>=sum) sum=rightnum;
}
return sum;
}
int main(){
int n,s;
int a[1000000];
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
s=start(a,0,n-1);
cout<<s;
return 0;
}
我们队3人,有一个因为生病的原因无法上课和我们一起做这个题目,我们在宿舍进行了讨论: