这道题打破了我常规的做题思路,因为这是我刚开始训练DP,感觉这道题目好晕眼呀,emm其实就是感觉自己是真的菜......

  为什么说打破了我的做题思路呢,因为我平时看题解都是在已经AC或者完全不懂的情况下看了题解用的知识点,然后再自学知识点完成题目,结果这次.......我是真的鸡...

  好了言归正传,看了刘汝佳大佬的线性dp和滚动数组类型的内容,也有一定的了解,下面我会解释什么情况下可以滚动数组降维减少空间复杂度,那么又该如何降维呢?

  

  本题大意:给定一个数字m和n个数字,让你求出这n个数字分为m份的和的最大值,具体分割要求见题目。

  

  本题思路:很显然就是dp了,由于题目要求是求将n个数字分割成m部分的和的最大值,那么从dp[ m ][ n ]开始考虑,dp[ m ][ n ]只与第n个数字的状态有关,我们可以先试着写一下状态转移方程

  dp[ i ][ j ] = max(dp[ i ][j - 1], dp[i - 1][ k ]) + a[ j ])( k >= 1 && k <= j - 1), 显然这个式子中有两部分,即当第 j 项直接加到j - 1项后面时为dp[ i ][ j ] = dp[ i ][j - 1] + a[ j ],当不直接加入时则第 j 项作为第 i 个子序列的开头,则dp[ i ][ j ] =  dp[i - 1][ k ] + a[ j ]。我们选择将第 i 个子序列与 第 i - 1个子序列中的最大值合并,我们将每次得到的最优值更新并保存即可。

  题目只给了32MB的空间,二维数组是不可能二维数组的了,顶多是滚动数组优化一下这样子......

  参考代码:

 //dp[i][j] 表示第j个数字在第i个序列时的最优值
#include <iostream>
#include <cstring>
using namespace std; const int N = 1e6 + , INF = 0x3f3f3f3f;
int a[N], dk[N], dp[N]; int main () {
int m, n, maxn;
while(cin >> m >> n) {
for(int i = ; i <= n; i ++)
cin >> a[i];
memset(dk, , sizeof dk);
memset(dp, , sizeof dp);
for(int i = ; i <= m; i ++) {
maxn = -INF;//初始化
for(int j = i; j <= n; j ++) {
cout << dk[j - ] << '\t';
if(i == j) dp[j] = dk[j - ] + a[j];//第i个元素只能作为第i个子序列的第一个元素
else dp[j] = max(dp[j - ] + a[j], dk[j - ] + a[j]);//选择两种决策中的最大值(直接接到j - 1后面或者以j再作为新的开头)
dk[j - ] = maxn;//maxn保存的是第j - 1位置的最优值
if(maxn < dp[j]) maxn = dp[j];//如果遇到更优的值则更新
//dk[j] = maxn;//那么我们为什么不这样呢,如果我们更新第j项那么意味着我们在下次计算dp[j + 1]时用到的dk[j] = dp[j] ??? 这明显与我们的状态转移方程不符合
//因为我们更新dp[j]时用到的是dk[j - 1],那我们只需要更新这个值即可。
}
cout << endl;
}
cout << maxn << endl;
}
return ;
}

  很容易可以看出,第 i 个子序列的最优值只与第i - 1层他对应的最优值有关,则对于dp[ i ][ j ] = max(dp[ i ][j - 1], dp[i - 1][ k ]) + a[ j ]),我们可以看出,只需要在遍历的时候依次访问他的子序列长度即可,并不需要保存每层的最优值,因为长度为 i 的子序列的最优解可以由第i - 1层的最优解得来,因此我们只需要保存一层的最优解,然后在计算下一层的最优解时更新保存的值即可......。

  我们可以用一个一维数组来保存我们在第i - 1层中遇到的最大值。切记是第i - 1层。

HDU_1024.MaxSumPlusPlus(基础DP + 滚动数组优化讲解)的更多相关文章

  1. [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp

    Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...

  2. LG3004 「USACO2010DEC」Treasure Chest 区间DP+滚动数组优化

    问题描述 LG3004 题解 把拿走的过程反向,看做添加的过程,于是很显然的区间DP模型. 设\(opt_{i,j}\)代表区间\([i,j]\)中Bessie可以获得的最大值,显然有 \[opt_{ ...

  3. poj1159 dp(滚动数组优化)

    H - 简单dp 例题扩展 Crawling in process... Crawling failed Time Limit:3000MS     Memory Limit:65536KB     ...

  4. 51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化

    基准时间限制:2 秒 空间限制:131072 KB  一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上.第1遍时只能向下和向右走,第2遍时只能向 ...

  5. 2014年北京 happy matt friends(dp + 滚动数组优化)

    Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Oth ...

  6. POJ 3666 Making the Grade (DP滚动数组)

    题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A[i],修理后是B[i],花费|A[i] – B[i]|,求最小花费.(数据有问题,代码只是单调递增的情况) #include <stdio ...

  7. Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)

    题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A ...

  8. dp,滚动数组优化

    51Nod1084矩阵取数问题 V2 题意: 一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上.第1遍时只能向下和向右走,第2遍时只能向上和向左 ...

  9. hdu 3392(滚动数组优化dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3392 Pie Time Limit: 6000/3000 MS (Java/Others)    Me ...

随机推荐

  1. NFS服务基本配置及使用

    操作系统:redhat 7.2 参考链接:https://www.cnblogs.com/dscode/p/6146409.html NFS:Network File System 一.服务器端配置 ...

  2. element 表格无法绑定服务返回数据

    无法直接绑定返回的Object属性,需要用js做一次对象转换后,才能绑定 <template> <div> <!--<button>添加服务器</but ...

  3. 判断窗体 show完成

    TForm窗体 this->Visible           this->Showing        true: 显示 fale:关闭     这个可用    this->Act ...

  4. 深度学习原理与框架-神经网络-线性回归与神经网络的效果对比 1.np.c_[将数据进行合并] 2.np.linspace(将数据拆成n等分) 3.np.meshgrid(将一维数据表示为二维的维度) 4.plt.contourf(画出等高线图,画算法边界)

    1. np.c[a, b]  将列表或者数据进行合并,我们也可以使用np.concatenate 参数说明:a和b表示输入的列表数据 2.np.linspace(0, 1, N) # 将0和1之间的数 ...

  5. 机器学习入门-文本数据-构造Ngram词袋模型 1.CountVectorizer(ngram_range) 构建Ngram词袋模型

    函数说明: 1 CountVectorizer(ngram_range=(2, 2)) 进行字符串的前后组合,构造出新的词袋标签 参数说明:ngram_range=(2, 2) 表示选用2个词进行前后 ...

  6. 尚硅谷redis学习6-持久化RDB

    是什么 持久化文件保存在dump.rdb中 持久化策略 在shutdown或flush或flushall后会立即持久化 重新启动后会从rdb文件中恢复数据 可以手动持久化 持久化失败时不允许写,如在强 ...

  7. Spring STS Call Hierarchy 查找不到被调用的信息

    今天使用Spring的STS的时候,发现Call  Hierarchy无法使用,很奇怪,发现问题出现在同一个工作区间里,如果工作区间不在此工作区间,发现还是可以找到被调用的信息的.当时在网上找也没找到 ...

  8. Reduction: the word AT

    Reduction: the word AT Share Tweet Share Tagged With: AT Reduction Study the AT reduction.  There ar ...

  9. 遍历DOM树,获取所有兄弟节点

    获取兄弟节点的常用方法有:  方法  说明 siblings()  选取所有兄弟节点 next()  选取后面兄弟节点 nextAll()  选取所有后面的兄弟节点 nextUntil()  选取所有 ...

  10. Unity3D脚本学习——运行时类

    AssetBundle 类,继承自Object.AssetBundles让你通过WWW类流式加载额外的资源并在运行时实例化它们.AssetBundles通过BuildPipeline.BuildAss ...