HDU-1024-DP局
Max Sum Plus Plus
这次来写点hdu的博客啦~最近在练习dp哈,都是些简单dp,不过一天玩玩洒洒好像也写不了多少题目=-=刚刚教完老爸制表格,害,我可真是个小贴心鬼,不喜欢线上上课啊啊啊=-=
说好的dp局就一定要去完成~
题目的大致意思就是给你一组序列,把这组序列分成指定组,然后组间的元素不能重叠=-=但是可以数量不一样,然后组内元素不允许间断,需要连续的序列=-=,然后问你分成的这么多组的最大和是多少
这是一个dp题,dp题,dp题!!子段和最大值问题
解题思路:
我们用dp[i][j]表示将前 j 个元素分为 i 个组的最大和。
这里的状态方程这样描述:
我们考虑第 j 个元素的状态,到底是单独一组还是和其他的一组,于是就分为了两种情况
dp[i][j] = max(dp[i][j - 1] + a[j], max(dp[i - 1][k]) + a[j])
dp[i][j - 1] + a[j]代表将前j - 1个数分为 i 组,将a[j]放在前一组里面,也就是说元素组别是连续的,没有间断
max(dp[i - 1][k]) + a[j] (0 < k < j) 在其中找到最大的一个,将前k个分为i - 1组,a[j]单独成为一组,也就是说不同组别中的元素不是连续的
我们采用压缩方式啦~也叫做滚动数组
一维代替二维
max(dp[i - 1][k])是在其中找到上一轮的最大值,所以我们再弄一个数组保存最大值就可以啦~
这就是用空间换时间啦~
下面是代码部分啦~
#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e6 + 10;
const int INF = 1e9 + 10;
int a[N];
int dp[N];
int maxx[N];
int ma;
int main()
{
int m, n;
while (~scanf("%d%d", &m, &n))
{
for (int i = 1; i <= n; i++)
{
scanf ("%d", &a[i]);
}
mst(dp, 0);
mst(maxx, 0);
for (int i = 1; i <= m; i++)
{
ma = -INF;
for (int j = i; j <= n; j++)
{
dp[j] = max(dp[j - 1] + a[j], maxx[j - 1] + a[j]);
maxx[j - 1] = ma;
ma = max(ma, dp[j]);
}
}
cout << ma << endl;
}
return 0;
}
我们用ma记录最后要求组别的最大值,就直接用ma存下来啦~
我们明天见,啊啊啊啊有点纠结啊,到底我是裸机装linux还是装双系统啊啊啊。纠结啊啊啊~~我得好好思考一下!