看别人题解写出来的,指路:https://blog.51cto.com/13688928/2117013
题目意思:在一个数列里找m个字段,使得他们的和最大。
dp[i][j]来表示在前j个数中,以下标j结尾并分为i段的最大和。
动态转移方程:dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][k]) + a[j] ) (0<k<j)
下面解释k的意义:
max( dp[i-1][k] ) + a[j] )表示的前k个数分成i-1组时的最大值。
所以也要对k进行遍历来求解max(dp[i-1][k]),但这样显然会超时。所以可以用一个pre【】数组来记录前j个分为i组的最大值。
#include <iostream>
#include<stdio.h>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <queue>
//#include <bits/stdc++.h>
#define pb push_back
#define qc std::ios::sync_with_stdio(0);
using namespace std;
const int max_n=1000005;
typedef long long ll;
typedef unsigned long long int ul;
typedef double dl;
int a[max_n],pre[max_n];
int dp[max_n];
int main()
{
int n,m,maxn;
while(~scanf("%d %d",&m,&n))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(dp,0,sizeof(dp));
memset(pre,0,sizeof(pre));
for(int i=1;i<=m;i++)
{
maxn=-1000000;
for(int j=i;j<=n;j++)
{
dp[j]=max(pre[j-1],dp[j-1])+a[j];
pre[j-1]=maxn;
maxn=max(maxn,dp[j]);
}
}
printf("%d\n",maxn);
}
}


京公网安备 11010502036488号