https://pintia.cn/problem-sets/994805342720868352/problems/994805514284679168
方法一: 前綴和+枚舉 時間復雜度: O(n2)
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e5+10;
int s
[N
],n
;
int startx
,endx
,ans
=-1e9;
bool flag
;
int main(void)
{cin
>>n
;for(int i
=1;i
<=n
;i
++){cin
>>s
[i
];if(s
[i
]>=0) flag
=true;s
[i
]+=s
[i
-1];}if(!flag
){cout
<<0<<" "<<s
[1]<<" "<<s
[n
]-s
[n
-1];return 0;}for(int i
=1;i
<=n
;i
++){for(int j
=i
;j
<=n
;j
++){int sum
=s
[j
]-s
[i
-1];if(sum
>ans
){ans
=sum
;startx
=s
[i
]-s
[i
-1];endx
=s
[j
]-s
[j
-1];}}}cout
<<ans
<<" "<<startx
<<" "<<endx
;return 0;
}
方法二: 前綴和+貪心 時間復雜度O(n)
s[l,r]=s[r]-s[l-1] 故對每一個以r結尾的區間,我們讓減的數s[l-1]最小,那么此時以r結尾的所有區間就可以求一個最大值。
即在[0,r-1]中取一個最小的值。
對于每一個r結尾的區間的最大和中,求一個最大值,即可求整個數組的一個最大的區間和。
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e5+10;
int s
[N
],n
;
bool flag
;
int ans
=-1e9,startx
,endx
;
int main(void)
{cin
>>n
;for(int i
=1;i
<=n
;i
++) {cin
>>s
[i
];if(s
[i
]>=0) flag
=true;s
[i
]+=s
[i
-1];}if(!flag
){cout
<<0<<" "<<s
[1]<<" "<<s
[n
]-s
[n
-1];return 0;}int temp
=1e9;int index
=0;for(int i
=1;i
<=n
;i
++){if(temp
>s
[i
-1]) temp
=s
[i
-1],index
=i
;int sum
=s
[i
]-temp
;if(sum
>ans
) ans
=sum
,startx
=index
,endx
=i
;}cout
<<ans
<<" "<<s
[startx
]-s
[startx
-1]<<" "<<s
[endx
]-s
[endx
-1];return 0;
}
方法三: 雙指針+貪心 時間復雜度O(n)
感覺寫的有點問題,有一個測試點,應該是最后故意卡的過了
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e5+10;
int ans
=-1e9,sum
,startx
,endx
;
int s
[N
],n
;
int main(void)
{cin
>>n
;int flag
=true;for(int i
=0;i
<n
;i
++){cin
>>s
[i
];if(s
[i
]>=0) flag
=false;} if(flag
){cout
<<0<<" "<<s
[0]<<" "<<s
[n
-1];return 0;}for(int i
=0,j
=0;i
<n
;i
++){sum
+=s
[i
];while(sum
<0) sum
=sum
-s
[j
],j
++; if(sum
>ans
) {ans
=sum
;startx
=s
[j
];endx
=s
[i
];}}if(ans
>0) cout
<<ans
<<" "<<startx
<<" "<<endx
;else cout
<<0<<" "<<0<<" "<<0;return 0;
}
總結
以上是生活随笔為你收集整理的1007 Maximum Subsequence Sum (25 分)【难度: 一般 / 知识点: 最大子序列和】的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。