- 題目鏈接: HDU 1024 Max Sum Plus Plus
題意:
- 給出n個數, 取其中不相交的m個連續序列的累加和,問最大值爲多少構造dp方程
- 最直觀的方程: dp[i][j] = MAX( dp[i-1][j]+a[i], dp[k][j-1]+a[i]) ( 1<=k < i )
- 其中dp[i][j]表示,在必須取第i個數的前提下,將前i個數分成j段的最大值
- 數據範圍n->[1, 1000000], 而m未知,這種情況下,m稍微大點就會出現爆空間了,所以需要數組降維
- 在不考慮a[i]的情況下,dp[i][j]只與dp[i-1][j]和MAX(dp[k][j-1]) (1< = k< i ) 有關。故只需要開兩個數組,分別記錄
- ① dp[j]記錄前i個數分成j段的最大值, (在未更新前i個數分成j-1段的最大值之前, dp[j-1]爲將前i-1分成j-1段的最大值)
- ② dp2[j]記錄dp[k][j-1] (1 <= k < i) 的最大值
- 在不考慮a[i]的情況下,dp[i][j]只與dp[i-1][j]和MAX(dp[k][j-1]) (1< = k< i ) 有關。故只需要開兩個數組,分別記錄
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define repp(i, a, b) for(int i=(b); i>=(a); --i)
#define rep(i,a,b) for (int i=(a); i<=(b); ++i)
#define de(x) cout<< #x << " => " << (x) << endl
#define ms(a, b) memset(a, b, sizeof(a))
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int inf = 0x3f3f3f3f;
const double PI=acos(-1);
const double eps=1e-9;
inline void file_put() {
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
}
const int maxn = 1e6+5;
int n, m;
int a[maxn];
ll dp1[maxn], dp2[maxn];
int main() {
// file_put();
while(~scanf("%d %d", &m, &n)){
rep(i, 1, n){
scanf("%d", &a[i]);
}
ms(dp2, 0);
dp1[0]=0;
ll ans=-inf*inf;
rep(i, 1, m){
ans = -inf*inf;
rep(j, i, n){
dp1[j] = max(dp1[j-1]+a[j], dp2[j-1]+a[j]);
dp2[j-1] = ans;
ans = max(ans, dp1[j]);
}
}
cout << ans <<endl;
}
return 0;
}