版权声明:欢迎转载学习! https://blog.csdn.net/m0_38081836/article/details/84069023
题意:给出一个数列,需要找出k个连续字段,让他们的和最大。
题解:动态规划,首先可以假设
为加上第j个数字分成i段的最大值,然后存在转移方程
然后我们发现状态的转移只需要当前状态的前一步
已经一个上一个状态的最大值
,所以并没有必要开二维的数组,所以我们需要开一个MAX数组来记录上一个状态到达
点的时候前面所有dp的最大值用来转移到当前状态即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
#define MAXSIZE 10
#define DLEN 4
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
class Kattis_maximumsubarrays {
public:
Kattis_maximumsubarrays();
~Kattis_maximumsubarrays();
void input();
void init();
void solve();
private:
ll *dp, *MAX, *a;
int n, m;
};
int main() {
Kattis_maximumsubarrays * pro = new Kattis_maximumsubarrays();
pro -> solve();
delete pro;
pro = NULL;
return 0;
}
Kattis_maximumsubarrays::Kattis_maximumsubarrays() {
dp = new ll[maxn];
MAX = new ll[maxn];
a = new ll[maxn];
}
Kattis_maximumsubarrays::~Kattis_maximumsubarrays() {
delete []dp;
delete []MAX;
delete []a;
dp = NULL;
MAX = NULL;
a = NULL;
}
void Kattis_maximumsubarrays::input() {
scanf("%d%d", &n, &m);
rep(i, 1, n) {
scanf("%lld", &a[i]);
}
}
void Kattis_maximumsubarrays::init() {
for(int i = 0; i < maxn;i ++) dp[i] = MAX[i] = 0;
}
void Kattis_maximumsubarrays::solve() {
init();
input();
ll ans = -1e18;
rep(i, 1, m) {
ans = -1e18;
rep(j, i, n) {
dp[j] = max(dp[j - 1] + a[j], MAX[j - 1] + a[j]);
MAX[j - 1] = ans;
ans = max(ans, dp[j]);
}
}
printf("%lld\n", ans);
}