Max Sum Plus Plus
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024
题目大意:
给一个$n$个元素的数组,允许选择$m$个连续区间,区间无重叠,求这$m$个区间的元素和最大值。
解题思路:
可以计算取一段区间,取两段区间,再到取$m$段区间的最大值,在过程中我们建立一个滚动的$dp$数组,记录前i项,取j段区间时(要求一定取第$i$个元素)所能取到的元素和最大值,同时用一个$p$数组,记录在前$i-1$个元素中取$m-1$个区间的最大值。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define rep(i,a,b) for(i=a;i<=b;i++) 5 #define debug(a) cout<<#a<<":"<<a<<endl; 6 const ll INF=1e18+7; 7 const ll N=1e6+7; 8 const ll mod=1e9+7; 9 ll maxn,minn; 10 ll T,n,m; 11 ll arr[N]; 12 ll dp[N]; 13 ll p[N]; 14 15 int main(){ 16 while(cin>>m>>n){ 17 memset(dp,0,sizeof(dp)); 18 memset(p,0,sizeof(p)); 19 for(ll i=1;i<=n;i++){ 20 scanf("%lld",arr+i); 21 } 22 for(ll i=1;i<=m;i++){ //先计算取一个区间一直到m个区间。 23 maxn=-INF; //因为存在负数 24 for(ll j=i;j<=n;j++){ //计算在前j个元素中取i个区间能得到的最大值 25 dp[j]=max(dp[j-1]+arr[j],p[j-1]+arr[j]); //dp数组记录的是前j个元素并包含第j个元素 26 //所能取到的最大值。 27 p[j-1]=maxn; //同时记录前j-1项取i个区间的最大值,计算p[j-1]是因为p也是一个滚动数组,不能破坏还有用的数据。 28 maxn=max(maxn,dp[j]); 29 } 30 } 31 cout<<maxn<<endl; 32 } 33 34 return 0; 35 }