/*
translation:
给出一串数列,求m个不相交的段最大的和是多少?
solution:
基本dp。
设dp[i][j]表示前j个数划分成i段,所得到的最优解。
对于第j个数,有两种决策,一种是单独成立成一个段。另一种是和地i个段组成一段。
所以有转移方程如下:dp[i][j]=max{dp[i][j-1], max{dp[i-1][k]}} + a[i]。其中k>=1 && k <= j-1
由于数据量太大,所以不能开二维数组。必须利用滚动数组。
再进一步观察可以发现,max{dp[i-1][k]}可以通过每次循环的更新来求出。如此以来,复杂度从O(mn^2)降成O(mn)
note:
1:注意最后输出时要输出tmp,原因见注释
# 状态的表示方法想错了,一开始想法是求出数列中和最大的段,在依次求出次小的。。。正确与否未知,但明显超时
* 关于状态表示方法的设计有个小诀窍,可以将题中所有的有关参数都列出来,将其依次组合。再推其转移方程,如果转移方程
满足动态规划的一系列要求,既是正确方法
* 若是有遇到数据量过大开不下多维数组的情况,可以考虑在开一个一维数组来代替。
date:
2016.10.29
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1000000 + 5;
const int inf = 1e8;
typedef long long ll;
int dp[maxn], a[maxn], pre[maxn];
int n, m;
int main()
{
//freopen("in.txt", "r"
hdu1024(基本dp)
最新推荐文章于 2017-11-13 02:36:15 发布
该博客讨论了如何使用动态规划求解一个问题,即在给定数列中找到m个不相交段的最大和。博主通过设定dp数组并利用滚动数组降低复杂度,将时间复杂度从O(mn^2)降至O(mn)。代码中展示了具体的动态规划实现,并特别指出最终答案是最后一轮的最大值,而不是dp[n]。
摘要由CSDN通过智能技术生成