您的位置:首页 > 其它

hdu 1024 Max Sum Plus Plus (dp优化)

2014-11-27 00:42 656 查看
题意:

给出n个数,求这n个数分成m个字段,并且这m个字段的最大和。

题解:

dp[i][j]表示前j个点分成i个字段对应字段的最大和。因为m比较小所以可以看成常熟,那么这样的复杂度是O(n^2),肯定是要TL的,那么如何有话呢?

先来看下原始的状态方程:

dp[i][j] = max{ dp[i][j-1] + a[j] , dp[i-1][k] + a[j] } a[j]要么放令外变成一段,要么加入到原来的分段中。观察能发现dp[i-1][k]其实是可以记录下来的,通过动态数组g[j]记录前j-1个这样的dp[i-1][k]中最大的值是多少,每次转移的不断的跟新。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int oo = 0x3f3f3f3f;
const ll OO = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
#define lson rt<<1
#define rson rt<<1|1
void cmax(int& a, int b){ if (b>a)a = b; }
void cmin(int& a, int b){ if (b<a)a = b; }
void cmax(ll& a, ll b){ if (b>a)a = b; }
void cmin(ll& a, ll b){ if (b<a)a = b; }
void cmax(double& a, double b){ if (a - b < eps) a = b; }
void cmin(double& a, double b){ if (b - a < eps) a = b; }
void add(int& a, int b, int mod){ a = (a + b) % mod; }
void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }
const int MOD = 100007;
const int maxn = 1100000;
int a[maxn];
int f[maxn], g[maxn];

int main(){
	//freopen("E:\\read.txt", "r", stdin);
	int n, m, mx;
	while (scanf("%d %d", &m, &n) != EOF){;
		for (int i = 1; i <= n; i++)scanf("%d", &a[i]);
		memset(f, 0, sizeof f);
		memset(g, 0, sizeof g);
		for (int i = 1; i <= m; i++){
			mx = -oo;
			for (int j = i; j <= n; j++){
				f[j] = max(f[j - 1], g[j - 1]) + a[j];
				g[j - 1] = mx;
				cmax(mx, f[j]);
			}
		}
		printf("%d\n", mx);
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: