Maximum Subarrays
题意:
输入
n
,
k
(
1
≤
k
≤
n
≤
5000
)
;
n,k(1\leq k\leq n\leq5000);
n,k(1≤k≤n≤5000);
第二行输入
a
1
,
a
2
,
…
,
a
n
(
−
1
e
9
−
1
e
9
)
a_1,a_2,\dots,a_n(-1e9-1e9)
a1,a2,…,an(−1e9−1e9);
求最大
k
k
k子段和,每一段必须是连续的。
题解:
没什么好讲的,直接
d
p
dp
dp
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示前
i
i
i个数取
a
i
a_i
ai的最大
j
j
j段和,
m
x
[
i
]
[
j
]
=
m
a
x
k
=
0
i
d
p
[
k
]
[
j
]
mx[i][j]=max_{k=0}^{i}dp[k][j]
mx[i][j]=maxk=0idp[k][j];
转移方程:
d
p
[
i
]
[
j
]
=
a
i
+
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
m
x
[
i
−
1
]
[
j
−
1
]
)
dp[i][j]=a_i+max(dp[i-1][j],mx[i-1][j-1])
dp[i][j]=ai+max(dp[i−1][j],mx[i−1][j−1])
m
x
[
i
]
[
j
]
=
m
a
x
(
m
x
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
]
)
mx[i][j]=max(mx[i-1][j],dp[i][j])
mx[i][j]=max(mx[i−1][j],dp[i][j])
注意初始化,下标要从0开始,不然很容易就
W
A
WA
WA了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5009;
ll dp[N][N],n,k,a[N],mx[N][N];
int main(){
//freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=0;i<=n;i++)for(int j=0;j<=k;j++)dp[i][j]=mx[i][j]=-1e18;
dp[0][0]=0;
for(int i=0;i<=n;i++)mx[i][0]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)if(i>=j)dp[i][j]=max(dp[i-1][j],mx[i-1][j-1])+a[i],mx[i][j]=max(mx[i-1][j],dp[i][j]);
cout<<mx[n][k]<<endl;
return 0;
}