51Nod1050 迴圈陣列最大子段和(動態規劃)
阿新 • • 發佈:2018-12-02
這題區間是可以迴圈的,如果不迴圈的狀態轉移方程是
if(dp[i-1]>0)
dp[i]=dp[i-1]+a[i];
else
dp[i]=a[i];
現在題目要求是可以迴圈,分為兩種情況:
1、沒有迴圈,找到了最大的子段。
2、迴圈了,找到了最大的子段。
第一種情況很簡單,第二種解決方法就是找到最小的子段,陣列和減去最小子段和,就是最大迴圈子段和。
#include <iostream> #include<cstring> typedef long long ll; using namespace std; ll dp[50005],a[50005]; int main() { ll n,i,sum=0; cin>>n; for(i=0;i<n;i++) { cin>>a[i]; sum+=a[i]; } memset(dp,0,sizeof(dp)); for(i=0;i<n;i++)//找最大子段 if(dp[i-1]>0) dp[i]=dp[i-1]+a[i]; else dp[i]=a[i]; ll min=1e9+7,max=0; for(i=0;i<n;i++) if(max<dp[i]) max=dp[i]; for(i=0;i<n;i++)//找最小子段 if(dp[i-1]<0) dp[i]=dp[i-1]+a[i]; else dp[i]=a[i]; for(i=0;i<n;i++) if(min>dp[i]) min=dp[i]; min=sum-min; cout<<(min>max?min:max)<<endl; }