日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

1007. Maximum Subsequence Sum (25)

發布時間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1007. Maximum Subsequence Sum (25) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:


10 1 4

錯誤代碼如下:

#include <stdio.h>int MaxSubseqSum4(int A[], int N, int* pstart, int* pend) {int i = 0;int tempStart; //記錄最大子段和位置int thisSum = 0, sum = 0;tempStart = 0;for (i = 0; i < N; i++) {thisSum += A[i];if (thisSum > sum) {sum = thisSum;*pstart = tempStart;*pend = i;} else if (thisSum < 0) {thisSum = 0;tempStart = i + 1;//每次及時更新,但不一定是最大和的首位置}}return sum; }int main() {int N = 0;int A[10001] = {0};int i;int flag = 0;int start, end, sum;scanf("%d", &N);for (i = 0; i < N; i++) {scanf("%d", A+i);if (*(A+i) >= 0) {flag = 1;}}if (flag == 0) { //如果序列的值全部<0printf("0 %d %d", A[0], A[N-1]);} else {sum = MaxSubseqSum4(A, N, &start, &end);printf("%d %d %d", sum, A[start], A[end]);}return 0; }
錯誤提示:

異常退出???什么原因呢?

用 下面的例子可以明白

3

-1 0 0

這個測試數據代入程序,發現start,end兩個變量沒有被操作,而且也沒有初始化,所以異常退出。

所以程序出錯就是這個例子沒有通過,所以必須考慮到這種情況,重新修改函數

MaxSubseqSum4
代碼如下:

#include <stdio.h>int MaxSubseqSum4(int A[], int N, int* pstart, int* pend) {int i = 0;int tempStart; //記錄最大子段和位置int thisSum = 0, sum = -1;tempStart = 0;for (i = 0; i < N; i++) {thisSum += A[i];if (thisSum > sum) {sum = thisSum;*pstart = tempStart;*pend = i;} else if (thisSum < 0) {thisSum = 0;tempStart = i + 1;//每次及時更新,但不一定是最大和的首位置}}return (sum > 0 ? sum : 0); }int main() {int N = 0;int A[10001] = {0};int i;int flag = 0;int start, end, sum;scanf("%d", &N);for (i = 0; i < N; i++) {scanf("%d", A+i);if (*(A+i) >= 0) {flag = 1;}}if (flag == 0) { //如果序列的值全部<0printf("0 %d %d", A[0], A[N-1]);} else {sum = MaxSubseqSum4(A, N, &start, &end);printf("%d %d %d", sum, A[start], A[end]);}return 0; }
測試結果:

上面的代碼在時間上已經達到O(n),但是空間上是相當浪費的(A[10000]),而且如果數據再多了就出現了溢出的錯誤,針對這兩點,修改代碼如下:(參考了http://www.2cto.com/kf/201311/254392.html的代碼)

下面是別人的優秀代碼,此代碼思路非常清晰簡潔:

#include<iostream> using namespace std; int main() { int N; int *input; int i; int begin=0, end=0, sum=0; //最終所求的子序列的起始位置,終止位置,以及子序列和。 int tempSum=0, tempBegin=0, tempEnd=0; //目前正在考察的子序列的起始位置,終止位置,以及子序列的和。 cin>>N; input = new int[N]; for(i=0; i<N; i++) cin>>input[i]; end = N-1; for(i=0; i<N; i++) { if(tempSum >= 0) { tempSum += input[i]; tempEnd = i; } else { //如果tempSum<0,那么tempSum+input[i]<input[i] //所以此時我們要開始考察新的子序列 tempSum = 0; tempSum += input[i]; tempBegin = i; tempEnd = i; } //if(tempSum > sum) 這樣寫不能AC,應改為如下: if(tempSum > sum || (tempSum == 0 && end == N-1)) //{ sum = tempSum; begin = tempBegin; end = tempEnd; } } cout<<sum<<" "<<input[begin]<<" "<<input[end]<<endl; return 0; }

下面對這段代碼做數學分析:

從集合的角度,所有的子段和可以分為三類:>0, <0, =0,<0的直接就不用考慮了,>0的直接用tempSum > sum就可以處理這種情況,比較麻煩的是=0這種情況,根據題目要求,當tempSum == 0時必須更新begin,end的值,(題目中有:保證i,j都盡可能的小),但是只有第一次更新就行了,如果每次子段和為0都更新,否則就不能保證j盡可能的小了,于是有了end == N-1這個條件。如測試數據2 1 -1.

代碼優化成在線方式,代碼如下:

#include<iostream> using namespace std; int main() { int N; int a; int i; int begin=0, end=0, sum=0; //最終所求的子序列的起始位置,終止位置,以及子序列和。 int tempSum=0, tempBegin = 0, tempEnd=0, allBegin = 0, allEnd = 0; //目前正在考察的子序列的起始位置,終止位置,以及子序列的和。 int flag = 0; int allNeg = 1;cin>>N; for(i=0; i<N; i++) { cin >> a;if (i == 0) { //初始化tempBegin = a;allBegin = a;}if (i == N-1) { //初始化allEnd = a;}if (a >= 0) { ?//判斷是否全為負數allNeg = 0;}if(tempSum >= 0) //記錄當前tempSum值{ tempSum += a; tempEnd = a; } else { tempSum = 0; tempSum += a; tempBegin = a; tempEnd = a; }if(tempSum > sum || (tempSum == 0 && flag == 0)) { sum = tempSum; begin = tempBegin; end = tempEnd;flag = 1;} } if (allNeg == 1)cout << "0" << " " << allBegin <<" "<< allEnd << endl; elsecout << sum << " " << begin << " " << end << endl;return 0; }
可對照上面的代碼理解此代碼,優化過的代碼比較難讀。

總結

以上是生活随笔為你收集整理的1007. Maximum Subsequence Sum (25)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。