第12週-C-必要な質問-3

トピック

東洞は、学期ごとに建物を掃除する仕事を引き受け、各寮の人数を数えるために寮に行きます。
各寝室にはaiの個人がいます(1 <= i <= n)。i番目からj番目の寮まで、合計(i、j)= a [i] +…+ a [j]の個人がいます。
これにより、寮の叔母はとても幸せになり、建物をm回掃除する必要があります。 iからj番目の寮sum(i、j)まで、
問題はsum(i1、j1)+…+ sum(im、jm)の最大値を見つけることです。また、ix <= iy <= jxおよびix <= jy <= jxは許可されていません。つまり、m個のセグメントはどれも交差できません。
注:1≤i≤n≤1e6、-32768≤ai≤32767人数はマイナスになる場合があります。(1 <= n <= 1000000)

入力

mと入力し、nと入力します。入力naiが続き、EOFに処理されます

出力

最大合計を出力

サンプル入力

1 3 1 2 3
2 6 -1 4 -2 3 -2 3

サンプル出力

6
8

アイデア

状態遷移方程式は、dp [i] [j] = max(dp [i] [j-1] + a [j]、dp [i-1] [k] + a [j])、dp [i] [です。 j]は、最初のj個の数値をi個のセグメントに分割して得られる合計の最大値を表します。pos配列を使用して、前の最大値を記録し、状態方程式を変更します。

コード

#include<iostream>
#include<string.h>
using namespace std;
const int maxn=1e6+10;
const int INF=0x0fffffff;
int n,m,ans,a[maxn],dp[maxn],pos[maxn];
int main()
{
    
    
	int m,n,ans;
	while(scanf("%d%d",&m,&n)!=EOF)
	{
    
    
		memset(dp,0,sizeof(dp));
		memset(pos,0,sizeof(pos));
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		for(int i=1;i<=m;i++)
		{
    
    
			ans=-INF;
			for(int j=i;j<=n;j++)
			{
    
    
				dp[j]=dp[j-1]>=pos[j-1]?dp[j-1]:pos[j-1];
				dp[j]+=a[j];
				pos[j-1]=ans;
				ans=ans>=dp[j]?ans:dp[j];				
			}			
		}
		printf("%d\n",ans);
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/alicemh/article/details/106149437