# 动态规划之最大子段和问题

1.穷举法

2.穷举法+前缀和

3.分治法

 1 int maxsum(int *a, int x, int y)//返回左闭右开区间的最大连续和
2 {
3     if(y - x == 1)return a[x];//只有一个元素，直接返回
4     int m = (x + y) / 2;
5     int maxs = max(maxsum(a, x, m), maxsum(a, m, y));//递归求解左右区间的最大值
6     int v = 0, L = a[m - 1], R = a[m];
7     //L为从分界点往左的最大连续和， R为分界点往右的最大连续和
8     for(int i = m - 1; i >= x; i--)L = max(L, v += a[i]);
9     v = 0;//清空之前的v
10     for(int i = m; i < y; i++)R = max(R, v += a[i]);
11     return max(maxs, L + R);//合并求解
12 }

4.动态规划法

 1 ll dp[maxn], a[maxn];
2 int main()
3 {
4     cin >> n;
5     for(int i = 1; i <= n; i++)
6     {
7         cin >> a[i];
8         dp[i] = a[i];
9     }
10     for(int i = 1; i <= n; i++)
11     {
12         dp[i] = max(dp[i], dp[i - 1] + a[i]);
13     }
14     ll ans = 0;
15     for(int i = 1; i <= n; i++)ans = max(ans, dp[i]);
16     cout<<ans<<endl;
17     return 0;
18 }

 1 　　cin >> n;
2     ll maxsum = 0;
3     ll thissum = 0;
4     int x;
5     for(int i = 1; i <= n; i++)
6     {
7         cin >> x;
8         thissum += x;
9         if(thissum > maxsum)
10         {
11             maxsum = thissum;
12         }
13         if(thissum < 0)
14         {
15             thissum = 0;
16         }
17     }
18     cout<<maxsum<<endl;

最大子段和变形：记录开始和结束点

posted @ 2018-03-30 17:07  _努力努力再努力x  阅读(9780)  评论(0编辑  收藏  举报