感觉有点奇怪的是这题明明是n^2的复杂度,n=1e6竟然能过= =。应该是数据水了。

  dp[i][j]表示前j个数,分成i段,且最后一段的最后一个为a[j]的答案。那么转移式是:dp[i][j] = max(dp[i][j-1], max{dp[i-1][t]}) + a[j],(i-1<=t<=j-1,j-1>=i)。前者表示在第i段的最后一个加上a[j],后者表示a[j]另起一段。这个dp显然是可以滚动数组的,那么空间是可以接受的。然后后者可以使用一个pre数组来记录之前的最大值。具体见代码:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int N = + ;
const int inf = 2e9; int m,n;
int a[N],dp[N],pre[N]; int main()
{
while(scanf("%d%d",&m,&n) == )
{
for(int i=;i<=n;i++) scanf("%d",a+i);
memset(pre,,sizeof(pre));
int temp;
for(int i=;i<=m;i++)
{
temp = -inf;
for(int j=i;j<=n;j++)
{
// 要加下面这行的特判,因为j和i相等的时候dp[j-1]是前一个i时候的状态
if(j == i) dp[j] = pre[j-] + a[i];
else dp[j] = max(dp[j-], pre[j-]) + a[j];
pre[j-] = temp; // 之所以只能这样更新是因为必须在旧状态的pre用完以后再更新新的pre
temp = max(temp, dp[j]);
}
}
printf("%d\n",temp);
}
return ;
}

  

  有几点想补充的。感觉如果用滚动数组,代码会更容易理解。个人认为上面这个特判不能少,因为j是必须大于i的,虽然少了也能过(应该是数据水了)。

另外,还是觉得这题应当是n^2规模的问题。顺便回顾一下之前一道类似的问题:选k段,每段的长度都为m,求区间的最大和

最新文章

  1. Unity StrangeIoC框架
  2. barManager 挤压后“ 自动换行”和“自动隐藏”的实现方法
  3. iOS常用方法
  4. js 模板引擎 为什么选择 dot
  5. 使用swipecard实现卡片视图左右滑动监听以及点击监听
  6. Linux:ssh连接服务器很慢
  7. node工具--connect
  8. Oracle EBS-SQL (SYS-14):查询表空间1.sql
  9. Vertica数据库操作
  10. 【prim + kruscal 】 最小生成树模板
  11. c++运行时类型识别(rtti)
  12. Windows 2008 R2下 如何简单使用IIS来配置PHP网站
  13. gulp使用流程
  14. HTML篇(下&#183;)
  15. shell设置连接服务器永不超时
  16. export及export default的区别
  17. webpack 学习总结demo
  18. bzoj 4044 Virus synthesis - 回文自动机 - 动态规划
  19. Windows server 2008 R2 安装指引
  20. 到底什么是ES索引?

热门文章

  1. Callable和Future的区别
  2. Get HttpWebResponse and HttpClient Return String by proxy
  3. React-脚手架
  4. zepto学习(二)之tap事件以及tap事件点透处理
  5. 1 java 笔记
  6. 【Java并发】线程安全和内存模型
  7. java 使用POI导出百万级数据
  8. web开发:css总结与应用
  9. YOLO---YOLOv3 with OpenCV安装与使用
  10. Python3+Appium学习笔记03-启动app