列表

详情


NC235953. 最大m个子段和

描述

给你一个数组 a ,包含 n 个整数,你需要在数组 a 中选出不相交的 m 个连续子段,每个子段的长度至少为 1 。
定义每一个子段的贡献为子段内数字的和,你需要求出这 m 个子段的贡献之和的最大值是多少。

输入描述

第一行输入两个正整数  ,表示数组 a 大小和子段个数。

第二行输入 n 个整数  ,表示数组 a 。

输出描述

输出一行一个整数,表示 m 个子段的贡献之和的最大值。

示例1

输入:

6 2
-1 4 -2 3 -2 3

输出:

8

说明:

选择的两个子段是[2,2],[4,6],和为4+3-2+3=8

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 221ms, 内存消耗: 17656K, 提交时间: 2022-09-29 21:27:28

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[1000010],last[1000010],a[1000010],res;
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for(int i=1;i<=m;i++){
        for(int j=i;j<=n;j++){
            dp[j]=dp[j-1]+a[j];
            dp[j]=max(dp[j],last[j-1]+a[j]);
            if(i==m)
            res=max(res,dp[j]);
        }
        for(int j=i;j<=n;j++){
        	last[j]=max(last[j-1],dp[j]);
		}
    }
    printf("%lld",res);
}

C++(clang++ 11.0.1) 解法, 执行用时: 353ms, 内存消耗: 17760K, 提交时间: 2023-08-03 14:32:55

#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e6+10;
ll dp[N],a[N],b[N],ans;int n,m;
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int j=1;j<=m;j++)
	{
		for(int i=j;i<=n;i++)
		dp[i]=max(dp[i-1]+a[i],b[i-1]+a[i]),ans=max(ans,dp[i]);
		for(int i=1;i<=n;i++)
		b[i]=max(b[i-1],dp[i]);
	}
	cout<<ans<<endl;
}

上一题