题意:求一个序列中的最大 m 段和,m 段不能交叉。

dp[i][0/1][j] 表示已经取完第 i 个物品,第 i 个物品取或不取,取到第 j 个子段。

用vis[i][0/1][j] 表示该 dp 值是否存在。

然后当 vis[i][0][j] 存在,即第 i 个物品不取,之前已经取了 j 个子段,可推得:

  第 i+1 个不取: dp[i+1][0][j]=max(dp[i+1][0][j],dp[i][0][j]);

  第 i+1 个取: dp[i+1][1][j+1]=max(dp[i+1][1][j+1],dp[i][0][j]+a[i]);

当 vis[i][1][j] 存在,即第 i 个物品取,之前已经取了 j 个子段(第 j 段可能还没有取完),可推得:

  第 i+1 个不取: dp[i+1][0][j]=max(dp[i+1][0][j],dp[i][1][j]);

  第 i+1 个取且放在第 j 个子段中: dp[i+1][1][j]=max(dp[i+1][1][j],dp[i][1][j]+a[i]);

  第 i+1 个取且放在第 j+1 个子段中: dp[i+1][1][j+1]=max(dp[i+1][1][j+1],dp[i][1][j]+a[i]);

然后初始化 dp[1][1][1]=a[1],dp[1][0][0]=0;

由于直接开 n*2*m 会MLE,所以将第一维滚动,2*2*m 就完全没有问题,复杂度 O(n*m);

 #include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; typedef long long ll;
const int maxn=1e6+; int a[maxn];
int dp[][][];
bool vis[][][]; int main(){
int m,n;
while(scanf("%d%d",&m,&n)!=EOF){
for(int i=;i<=n;++i)scanf("%d",&a[i]);
memset(dp,,sizeof(dp));
memset(vis,,sizeof(vis));
dp[][][]=a[];
vis[][][]=;
dp[][][]=;
vis[][][]=;
for(int k=;k<n;++k){
int i=k&;
memset(vis[i^],,sizeof(vis[i^]));
for(int j=;j<=m;++j){
if(vis[i][][j]){
if(!vis[i^][][j]){
vis[i^][][j]=;
dp[i^][][j]=dp[i][][j];
}
else if(dp[i][][j]>dp[i^][][j])dp[i^][][j]=dp[i][][j];
if(!vis[i^][][j+]){
vis[i^][][j+]=;
dp[i^][][j+]=dp[i][][j]+a[k+];
}
else if(dp[i][][j]+a[k+]>dp[i^][][j+])dp[i^][][j+]=dp[i][][j]+a[k+];
}
if(vis[i][][j]){
if(!vis[i^][][j]){
vis[i^][][j]=;
dp[i^][][j]=dp[i][][j];
}
else if(dp[i][][j]>dp[i^][][j])dp[i^][][j]=dp[i][][j];
if(!vis[i^][][j]){
vis[i^][][j]=;
dp[i^][][j]=dp[i][][j]+a[k+];
}
else if(dp[i][][j]+a[k+]>dp[i^][][j])dp[i^][][j]=dp[i][][j]+a[k+];
if(!vis[i^][][j+]){
vis[i^][][j+]=;
dp[i^][][j+]=dp[i][][j]+a[k+];
}
else if(vis[i^][][j+]&&dp[i][][j]+a[k+]>dp[i^][][j+])dp[i^][][j+]=dp[i][][j]+a[k+];
}
}
}
int ans=-0x3f3f3f3f;
if(vis[n&][][m])ans=max(ans,dp[n&][][m]);
if(vis[n&][][m])ans=max(ans,dp[n&][][m]);
printf("%d\n",ans);
}
return ;
}

最新文章

  1. Canvas绘制图形
  2. NPOI读取Excel 数据 转。。。
  3. unity3d 射弹基础案例代码分析
  4. static关键字详解
  5. material design——设计文档
  6. hdu 2102
  7. Discuz论坛搭建过程
  8. 神马小说:使用opensearch打造高性能搜索服务
  9. ie6下:png图片不透明 和 背景图片为png的节点的内部标签单击事件不响应
  10. 新浪微博客户端开发之OAuth认证篇
  11. 《C++ Primer》之面向对象编程(四)
  12. Java框架之Spring MVC(二)
  13. 设计模式学习系列(一)——IOC设计原则
  14. DFS Tempter of the Bone
  15. LeetCode题解之Binary Tree Level Order Traversal II
  16. 记一次排查局网内的ARP包 “不存在的” MAC 地址及 “不存在的”IP 所发的ARP包
  17. 【Selenium-WebDriver自学】WebDriver交互代码(十一)
  18. javascript简单的选项卡
  19. javascript总结集合
  20. [svc]lnmp一键安装脚本(含有np与mysql分离)

热门文章

  1. leetcode日记 Combination sum IV
  2. JSON介绍
  3. t4 加载文件到解决方案
  4. android:ToolBar详解
  5. 入住cnblogs第一篇随笔 Hello, world!
  6. 1.6jdk + eclipse + pydev搭建Python开发环境
  7. PHPstorm--ThinkStorm安装
  8. 【转】深入理解JavaScript闭包闭包(closure) (closure)
  9. BackTrack5-r3任务栏显示网络图标及自定义DNS
  10. nginx 之 grok 过滤