今天看刘汝佳看到归并排序还看了分治求最大子序列和,感觉简单多了,刚开始学时看了几天都没看会,现在在看感觉果然不一样^.^,先打一个归并排序,马上就打子序列和,
哎~为什么总打这些水题呢,一是我现在很水,二是涉及人生完不完整的八数码暂时理解不深(哈哈),勉强看懂,等过几天就会相对高级的算法了,这里复制上一段话是CXL学长写的:
如果说入门注重的是编程能力,那么第2步——起步,开始需要一些思维能力了。所谓思维能力,就是……嗯……比如智力题,小学奥数题,数学应用题,它有一定的灵光一现的成分。从第一个阶段到第二个阶段不要着急。慢慢做就好了。有些人会很快,路了。但更多的人会卡一下。这时候原因是他已经有了这样的思维能力,经过几道题的启发,他就知道是什么套,淡定,别急。尽力做题,不会就看答案,然后想明白答案为什么正确,再尝试想一想,为什么我没想到,怎么样我才能想到?积累一些以后,自然就通了。
前面啰嗦了半天,我讲的是我自己的一个过程。最简单的行动指引是:与高中学数学、学物理等学科的方法相同。(教程 à 课本 or 上课, 题目 à 作业 or 试卷, 答案 à 课后答案)。有这么一个对应关系,你是不是不用再纠结到底看不看题解了?
归并:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 using namespace std; 5 void merge_sort(int *A,int x,int y,int *T)//T为temp,A为ans 6 { 7 if(y-x>1){ 8 int m=x+(y-x)/2; 9 int p=x,q=m,i=x;//i:合并完成后的开始,p,左数组的起点,q右数组的起点 10 merge_sort(A,x,m,T); 11 merge_sort(A,m,y,T); 12 while(p<m||q<y){//在不溢出本次排序的情况下进行 13 if(q>=y||(p<m&&A[p]<=A[q])) T[i++]=A[p++];//q=y的话右数组已经全部排玩,只能排左数组了或左数组小于右数组 14 else T[i++]=A[q++]; 15 } 16 for(i=x;i<y;i++) A[i] = T[i];//将最后拍好的数组放到A; 17 } 18 } 19 int main() 20 { 21 int A[20],T[20]; 22 int x=100,y=0,a,b; 23 while(cin>>a){ 24 for(int i=0;i<a;i++){ 25 cin>>A[i]; 26 if(A[i]<x) x=A[i]; 27 if(A[i]>y) y=A[i]; 28 } 29 merge_sort(A,0,a,T); 30 for(int i=0;i<a;i++) 31 cout<<A[i]<<" "; 32 } 33 }
子序列和:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int A[20]; int maxsum(int l,int r) { int mid=l+(r-l)/2; if(r-l==1){ return max(A[l],A[r]); } else{ int maxd=max(maxsum(l,mid),maxsum(mid,r)); int lsum,rsum,temp; temp=0;lsum=A[mid-1];//因为如果从零开始算的话不就和只有左右的情况一样了 for(int i=mid-1;i>=l;i--) lsum=max(lsum,temp+=A[i]);//其实我自己也想了一个但感觉没有刘汝佳的严谨,所以有一种只是变了变量名的感觉 rsum=A[mid];temp=0; for(int i=mid;i<r;i++) rsum=max(rsum,temp+=A[i]); return max(maxd,lsum+rsum); } } int main() { int n; while(cin>>n) { for(int i=0;i<n;i++) cin>>A[i]; int sum=maxsum(0,n); cout<<sum; } }