poj 1821 Fence





$ solution: $

这道题因为每一个粉刷的人都有一块“必刷的木板”,所以可以预见我们的最终方案里的粉刷匠一定是按其必刷的木板的顺序排列的。这就提示了我们可以用线性 $ DP $ ,只需要将粉刷匠按必刷的木板排序即可。

设 $ F[ $ i $ ][j] $ 表示前 $ i $ 个粉刷匠刷了前 $ j $ 快木板的最大收益(可以有木板不刷!)。我们可以根据题意列出转移方程:

  1. 首先这个粉刷匠一块木板也不刷
  2. 这块木板不刷
  3. 这个粉刷匠从第k块木板刷到第 $ j $ 块木板(这个有限制)

于是我们列出方程:

$ F[i][j]=max{F[i-1][j],\quad F[i][j-1],\quad ^{\quad max}_{j-L_i\leq k< S_i}{F[i-1][k]+P_i\times (j-k) } } $

然后我们发现前两个都好转移,但最后一个需要枚举耗费大量时间,而我们的数据范围就很不友好了。于是我们考虑如何优化:首先先将与k无关的项提取出来,这个可以直接放外面。

$ F[i][j]=^{\quad max}_{j-L_i\leq k< S_i}{F[i-1][k]-P_i\times k }+P_i\times j $

然后我们发现现在 $ max $ 函数里面的东西基本只和k有关, $ i $ 在循环枚举的外围可以相当于定值,于是我们可以用一个单调队列维护 $ F[i-1][k]-P_i\times k $ 这个东西,我们不能直接更新最大值,因为 $ j-L_i\leq k< S_i $ 会使我们之前的最大值失效,所以我们的单调队列需要满足双向删除,取队头(对头就是最优决策)。

总复杂度 $ O(N\times M) $



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int using namespace std; int n,m;
int b[16005];
int q[16005];
int f[105][16005]; struct su{
int l,s,v;
inline bool operator <(su x){
return s<x.s;
}
}a[105]; inline int ff(int i,int j){
return f[i-1][j]-a[i].v*j;
} inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
return sign?-res:res;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
m=qr(); n=qr();
for(rg i=1;i<=n;++i){
a[i].l=qr(); a[i].v=qr(); a[i].s=qr();
} sort(a+1,a+n+1);
for(rg i=1;i<=n;++i){ rg l=1,r=0;
for(rg j=max(0,a[i].s-a[i].l);j<a[i].s;++j){
while(l<=r&&ff(i,j)>=ff(i,q[r]))--r;; q[++r]=j;
}
for(rg j=1;j<=m;++j){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(j>=a[i].s){
while(l<=r&&q[l]<j-a[i].l)++l;
if(l<=r)f[i][j]=max(f[i][j],ff(i,q[l])+a[i].v*j);
}
}
}printf("%d\n",f[n][m]);
return 0;
}

最新文章

  1. com.panie 项目开发随笔_前后端框架考虑(2016.12.8)
  2. 反向输出及sort排序
  3. Qt QAxObject操作excel文件过程总结(转):
  4. C语言函数的读写
  5. codis配置
  6. 安装mmseg出错 config.status: error: cannot find input file: src/Makefile.in
  7. A script job for rebuild DB in AX 2012
  8. js禁止页面复制 禁用页面右键菜单的代码
  9. 【图像处理】Gabor过滤器
  10. C#中的动态特性
  11. 详解Bootstrap 定义按钮的样式(CSS)
  12. CF781D Axel and Marston in Bitland [倍增 矩阵乘法 bitset]
  13. C语言博客-指针
  14. CentOS7从U盘中拷贝文件
  15. Oracle dblink详解
  16. echarts参数详解--散点图
  17. oracle中文乱码的解决方法
  18. docker 容器和镜像理解
  19. C语言学习快速笔记
  20. (4.2)mysql备份还原——备份概述

热门文章

  1. Mahout0.9安装与配置(完全分布式模式下运行)
  2. BZOJ 1294 [SCOI2009]围豆豆Bean ——计算几何
  3. EC++学习笔记(六) 继承和面向对象设计
  4. Iptables入门教程
  5. 解决PHP无法接收post超过1000个字段的问题
  6. ROS安装环境配置及多版本的切换
  7. MySQL主从架构配置
  8. 洛谷 P3865 【模板】ST表
  9. 7.Java web&mdash;tomcat9部署
  10. iOS--基于键值的观察者模式(KVO)