n个数,切为m段,最大和 n,m<=5e3
dp[i][j],使用前i个数(!!!第i个数被使用!!!)
,分为j段的最大和.
每到一个点,他最大的这个dp状态,要不是和前面一个连着最大,要不就是不和前面一个连着的最大.
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#ifdef noob
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
#else
#define debug(...)
#endif
using namespace std;
typedef long long LL;
const int MAXN = 5e3 + 17;
const int MOD = 1000000007;
int a[MAXN];
LL dp[2][MAXN],mx[MAXN];
int main()
{
#ifdef noob
freopen("Input.txt","r", stdin);
freopen("Output.txt", "w", stdout);
#endif
int n,m;
cin>>n>>m;
for (int i = 0; i < n; ++i)
{
cin>>a[i+1];
}
LL ans = 0;
for (int i = 1; i <= m; ++i)
{
mx[i] = -1000000000;
dp[0][i] = dp[1][i] = -1000000000;
}
int now = 0,pre = 1;
for (int i = 1; i <= n; ++i)
{
swap(now, pre);
debug(i);
for (int j = min(m,i); j >= 1; --j)
{
dp[now][j] = mx[j-1]+a[i];
dp[now][j] = max(dp[now][j],max(dp[pre][j],dp[pre][j-1])+a[i]);
debug(j);
// debug(dp[i][j]);
mx[j] = max(1LL*mx[j],dp[now][j]);
debug(mx[j]);
ans = max(1LL*dp[now][j],ans);
}
}
cout<<ans<<endl;
return 0;
}