2018 ACM-ICPC North Central North America Regional Contest——Maximum Subarrays(dp(最大k子段和))

Maximum Subarrays

题意:

输入 n , k ( 1 ≤ k ≤ n ≤ 5000 ) ; n,k(1\leq k\leq n\leq5000); n,k(1kn5000);
第二行输入 a 1 , a 2 , … , a n ( − 1 e 9 − 1 e 9 ) a_1,a_2,\dots,a_n(-1e9-1e9) a1,a2,,an(1e91e9);
求最大 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[i1][j],mx[i1][j1])
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[i1][j],dp[i][j])
注意初始化,下标要从0开始,不然很容易就 W A WA WA了。

代码:

#include
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;
}

你可能感兴趣的:(DP)