- 算法2:
拿起脑子想的就是这个,so easy,除了注释一次通过(注释只有自己能懂系列)
#include <stdio.h>
#include <stdlib.h>//??? stblib.h
#define Maxsize 100000//MAXSIZE
int simplesearch(int p[],int b);
int main()
{
int b,i,j,maxadd;
//scanf("%d",&b);
int a[Maxsize];
scanf("%d",&b);
for(i=0;i<b;i++)
scanf("%d",&a[i]);
maxadd=simplesearch(a,b);
printf("%d",maxadd);
return 0;
}
int simplesearch(int p[],int b){
int maxadd=0;
int i,j,max;
for (i=0;i<b;i++){
max=0;
for(j=i;j<b;j++){
max+=p[j];
if(max>maxadd)
maxadd=max;
}
}
return maxadd;
}
- 算法4:在线搜索,是一种动态规划
惭愧惭愧,又回头看视频才知道怎么写
#include <stdio.h>
#include <stdlib.h>//??? stblib.h
#define Maxsize 100000//MAXSIZE
int onlinesearch(int p[],int b);
int main()
{
int b,i,j,maxadd;
//scanf("%d",&b);
int a[Maxsize];
scanf("%d",&b);
for(i=0;i<b;i++)
scanf("%d",&a[i]);
maxadd=onlinesearch(a,b);
printf("%d",maxadd);
return 0;
}
int onlinesearch(int p[],int b){
int max=0;
int i;
int thissum=0;
for(i=0;i<b;i++){
thissum+=p[i];
if(thissum>max)
max=thissum;
else if (thissum<0)//忘记了,看不懂就找MOOC
thissum=0;
}
return max;
}
算法3:分治,算是递归的进阶吧
附上分治法试用条件
- 该问题的规模缩小到一定的程度就可以容易地解决;
因为问题的计算复杂性一般是随着问题规模的增加 而增加,因此大部分问题满足这个特征。 - 该问题可以分解为若干个规模较小的相同问题,即该问 题具有最优子结构性质
这条特征是应用分治法的前提,它也是大多数问题可 以满足的,此特征反映了递归思想的应用。 - 利用该问题分解出的子问题的解可以合并为该问题的解;
能否利用分治法完全取决于问题是否具有这条特征,如果具 备了前两条特征,而不具备第三条特征,则可以考虑贪心算 法或动态规划。 - 该问题所分解出的各个子问题是相互独立的,即子问题之间 不包含公共的子问题。
这条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法 要做许多不必要的工作,重复地解公共的子问题(也就是本算法中求跨分界线的最大子列和 ),此时虽然也可用分 治法,但一般用动态规划较好(也就是算法4!!!)。
- 该问题的规模缩小到一定的程度就可以容易地解决;
分治法的基本步骤
divide-and-conquer(P)
{
if ( | P | <= n0) adhoc(P); //解决小规模的问题
divide P into smaller subinstances P1,P2,...,Pk;//分解问题
for (i=1,i<=k,i++)
yi=divide-and-conquer(Pi); //递归的解各子问题
return merge(y1,...,yk); //将各子问题的解合并为原问题的解
}
之前两个算法用dev不用调试,这个是visual stdio,方便调试,所以代码有点儿不同之处,纪念我第一次用vs写代码,并且调试后找出错误了
#include <stdio.h>
#include <stdlib.h>//??? NOTstblib.h
#define Maxsize 100000//MAXSIZE
int divideandconquer(int p[], int left, int right);
int max3(int a, int b, int c);
int main()
{
int b, i, maxadd;
//scanf("%d",&b);
int a[Maxsize];
scanf_s("%d", &b);
for (i = 0; i<b; i++)
scanf_s("%d", &a[i]);
maxadd = divideandconquer(a, 0, b - 1); //b-1
printf("%d", maxadd);
system("pause"); //为了不让结果准瞬即逝
return 0;
}
int divideandconquer(int p[], int left, int right) {
int mid, i;
int leftmax, rightmax;
int leftadd, rightadd;
int leftaddmax, rightaddmax;
leftaddmax = leftadd = 0; //放这试试
rightadd = rightaddmax = 0; //两遍不一样!!!
int max = 0;
/*if(b<2){
left=p[mid];
right=p[mid+1];
max=left>right?left:right;
*/
if (left == right) { //终止条件只有一个数字
if (p[left]>0) return p[left]; //不是[i]
else return 0;
}
mid = (left + right) / 2;
leftmax = divideandconquer(p, left, mid); //赋值给
rightmax = divideandconquer(p, mid + 1, right); //mid+1
for (i = mid; i >= left; i--){ //NOT i>=0 i有问题(for循环后多加了;)
leftadd += p[i]; //NOT p[mid]
if (leftadd>leftaddmax)
leftaddmax = leftadd;
}
for (i = mid + 1; i <= right; i++) { //NOT i>=0
rightadd += p[i]; //NOT p[mid]
if (rightadd>rightaddmax)
rightaddmax = rightadd;
}
return max3(leftmax, rightmax, leftaddmax + rightaddmax);
}
int max3(int a, int b, int c) {
return a>b ? (a>c ? a : c) : (b>c ? b : c); //输出大的就和大的比较,括号可省略
}