HDU——1024 Max Sum Plus Plus (dynamic programming + optimization)

Link to the original question: http://acm.hdu.edu.cn/showproblem.php?pid=1024

Insert picture description here
Test sample

Sample Input
1 3 1 2 3
2 6 -1 4 -2 3 -2 3
Sample Output
6
8

Meaning: give you a length of nninteger sequence of n num numn u m , let you findmmThe maximum sum of m non-repeated sub-segments.

Problem-solving ideas: This problem should be easy to think of dynamic programming, and the state is easier to find.We use dp [i] [j] dp[i][j]d p [ i ] [ j ] to expressiii sub-segments arenum [j] num [j]n u m [ j ] The largest sub-segment sum at the end. Then our initial state must bedp [0] [0] dp[0][0]d p [ 0 ] [ 0 ] , the final state ismax (dp [m] [t] max(dp[m][t]max(dp[m][t], m ≤ t ≤ n m\leq t≤n mtnSo how do we write this state transition equation? Think about it, isn't it d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ t ] , d p [ i ] [ j − 1 ] ) + n u m [ j ] , ( i ≤ t ≤ j − 1 ) dp[i][j]=max(dp[i-1][t],dp[i][j-1])+num[j],(i \leq t \leq j-1) dp[i][j]=max(dp[i1][t],dp[i][j1])+num[j],(itj1)(Because of our state definition, we must add the ending element, so the key is max maxm a x function, that is, the previous state is either the previousi − 1 i-1i1 maximum plus this tonum[j] num[j]n u m [ j ] as a new sub-segment, or pre-iiAddnum [j] num[j] tothe last field of i subsectionsn u m [ j ] .) Knowing this, can we start to do the problem? Let's observennn range, up to1e 6 1e61 e 6 . We simply can't open such a large array. And we have to perform a lot of redundant search operations (because we find every timedp [i] [j] dp[i][j]d p [ i ] [ j ] , must finddp [i − 1] [t] dp[i-1][t]dp[i1 ] The maximum value of [ t ] . ) This time complexity heightO (m × n 2) O(m\times n^2)O ( m×n2 ). This is obviously not feasible, so we need to optimize.

Optimization: Let’s take another look, for the two-dimensional dp dp we openedd p array, can we find a way to open it into one dimension?Of course, we can use loops to replace this effect, that is, perform mmm cycles, each cycle will add a new sub-segment. Then of course we want to optimize this new subsection.Let's look at the state transition equation again. According to our thinking, we need to solve and solve dp [i − 1] [t] dp[i-1][t]dp[i1 ] The problem of the maximum value of [ t ] , is this we found that we have already sought it in the previous state? That is, at thei − 1 i-1iIn 1 cycle, the maximum value we solved. Of course we can store this value. Then we can introduce an arraypre _ max pre\_maxp r e _ m a x array, usepre _ max [j − 1] pre\_max[j-1]pre_max[j1 ] meansdp [i − 1] [t] dp[i-1][t]dp[i1 ] The maximum value of [ t ] , this maximum value is naturally easy to find, that is, it is solved in the previous cycle. OK, look at the code specifically.

AC code

/*
*邮箱:[email protected]
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>	//POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e6+4;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int n,m;
int num[maxn];
int dp[maxn];
int pre_max[maxn];
int main(){
    
    
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	while(cin>>m>>n){
    
    
		rep(i,1,n){
    
    
			cin>>num[i];
		}
		memset(dp,0,sizeof(dp));
		memset(pre_max,0,sizeof(pre_max));
		int temp;
		rep(i,1,m){
    
    
			//m层循环,每层循环添加一个字段。但注意,我们添加的字段只能从i到n中添加。原因是因为字段必须包含一个元素。
			temp=-inf;//先初始化为最小值,这个保存的是临时最大值。
			rep(j,i,n){
    
    
				//这里利用的特点就是取消了第一维,转化为i来代替。
				dp[j]=max(pre_max[j-1],dp[j-1])+num[j];
				pre_max[j-1]=temp;//pre_max[j-1]存放i到j-1中的最大值。
				temp=max(temp,dp[j]);//temp存放i到j的最大值。
			}
		}
		cout<<temp<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/hzf0701/article/details/108985421