题意:有一道线性篱笆由N个连续的木板组成。有K个工人,你要叫他们给木板涂色。每个工人有3个参数:L 表示 这个工人可以涂的最大木板数目,S表示这个工人站在哪一块木板,P表示这个工人每涂一个木板可以得到的钱。要注意的是,工人i可以选择不涂任何木板,否则,他的涂色区域必须是连续的一段,并且S[i]必须包含在内。 最后还有,每块木板只能被涂一次。

解题思路:这是一道单调队列优化dp的问题,首先状态dp[i][j]表示第i个工人刷的最后一块木板为j,注意:木板可刷可不刷,工人也可以不刷任何墙。之前我忘记了,所以状态方程只写对了一半:dp[i][j] = max(dp[i][j],dp[i-1][k] + (j-k)*p[i]),这里还有,dp[i][j] = max(dp[i][j],dp[i-1][j],dp[i][j-1]) //第i个人不刷,第j面墙不刷

这里的关键是如何优化方程,注意到dp[i][j]=max(dp[i-1][k]-k*p[i])+j*p[i],可以直接维护dp[i-1][k]-k*p[i]的最大值即可,这里用到的就是单调队列。

参考博客:http://www.cnblogs.com/proverbs/archive/2012/10/04/2711751.html

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;struct Node
{int l,p,s;
}worker[105];
int n,k,dp[105][16005],q[16005];
int head,tail,l[105],r[105];bool cmp(Node a,Node b)
{return a.s < b.s;
}int main()
{while(scanf("%d%d",&n,&k)!=EOF){for(int i = 1; i <= k; i++)scanf("%d%d%d",&worker[i].l,&worker[i].p,&worker[i].s); sort(worker+1,worker+1+k,cmp);for(int i = 1; i <= k; i++){l[i] = max(worker[i].s - worker[i].l,0);r[i] = min(worker[i].s + worker[i].l - 1,n);}memset(dp,0,sizeof(dp));for(int i = 1; i <= k; i++){for(int j = 0; j <= n; j++) dp[i][j] = dp[i-1][j]; //第i名工匠不刷任何墙head = tail = 0;for(int j = l[i]; j < worker[i].s; j++) //将dp[i-1]层的最优状态存入单调队列 {int tmp = dp[i-1][j] - j * worker[i].p;while(head < tail && dp[i-1][q[tail-1]] - q[tail-1]*worker[i].p <= tmp) tail--;q[tail++] = j;}for(int j = worker[i].s; j <= r[i]; j++){while(head < tail && j - q[head] > worker[i].l) head++;   //弹出不在范围内的元素dp[i][j] = max(dp[i][j-1],dp[i-1][j]);dp[i][j] = max(dp[i][j],dp[i-1][q[head]] + (j - q[head]) * worker[i].p);}for(int j = r[i] + 1; j <= n; j++)dp[i][j] = max(dp[i-1][j],dp[i][j-1]);}printf("%d\n",dp[k][n]);}return 0;
}

poj 1821(单调队列优化dp)相关推荐

  1. poj 2373(单调队列优化dp)

    在长为L(<=1000000)的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的调节范围为[a,b].要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间必 ...

  2. POJ 1821 Fence(单调队列优化DP)

    题解 以前做过很多单调队列优化DP的题. 这个题有一点不同是对于有的状态可以转移,有的状态不能转移. 然后一堆边界和注意点.导致写起来就很难受. 然后状态也比较难定义. dp[i][j]代表前i个人涂 ...

  3. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  4. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  5. 【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

    题干: 在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币.但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币.因为这些数字都是可见的,所 ...

  6. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  7. 【单调队列优化DP】烽火传递 LibreOJ - 10180

    题目来源 点我进入提交题目 反思 因为目前在学习单调队列优化DP,所以会往单调队列上面想.然后犯了一个错误就是,认为这个题目只要用单调队列就可以完成,单调队列只是用来减少时间复杂度的,遇到了求最优解的 ...

  8. AcWing 1089 烽火传递 题解(动态规划—DP—单调队列优化DP)

    AcWing 1089 烽火传递 单调队列优化DP,思路比较简单,维护一个保持元素单调递增的单调队列,队首就是第i座烽火台能接收到的,代价最小的方案,加上第i座烽火台的代价就是这座烽火台的最小值 #i ...

  9. 【单调队列优化dp】jzoj4883灵知的太阳信仰 纪中集训提高B组

    [NOIP2016提高A组集训第12场11.10]灵知的太阳信仰 (File IO): input:array.in output:array.out Time Limits: 1000 ms Mem ...

最新文章

  1. Ansible05-部署文件
  2. 线段树-简单线段树模板
  3. 软工网络15个人阅读作业2——提问题
  4. 【codevs2452】【SCOI2005】【BZOJ1088】扫雷Mine
  5. [转]java中的值传递和引用传递
  6. 十八、Oracle学习笔记:PLSQL操作(含游标的操作)
  7. ASP.NET事件回传机制
  8. Windows10+Caffe+CUDA7.5+VS2013环境配置
  9. 计算机学院部长换届答辩,未来可期,各自精彩——记计算机科学学院2020年两委换届竞职答辩活动...
  10. SFP(Small Form-factor Pluggables)光模块
  11. 【论文分享】ACL 2020 立场检测相关研究
  12. java holder详解,Java基础系列18:Holder技术的实现原理分析
  13. 70 漂亮且极具亲和力的导航菜单设计推荐
  14. 《Presto(Trino)——The Definitive Guide》CHAPTER 6 Connectors Advanced CHAPTER 7 Connector Examples
  15. Office+Visio安装教程
  16. 【香橙派4B】1、重刷系统
  17. 数据分析-前置条件(采集、存储、治理)
  18. equest,response,session,cookie,application
  19. 雷军:《我十年的程序员生涯》系列之三(失败的大学创业经历)
  20. java简单爬虫实现打印小说章节至控制台

热门文章

  1. 华夏基金专访神策数据创始人兼 CEO 桑文锋,金融科技数字化趋势认知传递
  2. 节前福利 | 三位大佬带你从客户成功、销售、市场端打造 To B 运作体系 !
  3. 干货:如何在前端统计用户访问来源?
  4. 精益分析体系构建如何“因企制宜”?
  5. (五)开源IT资产管理系统--分发OCS客户端
  6. 【Linux】linux下gzip的压缩/解压缩详解
  7. 从内容云到一云多屏 云计算助力传统媒体转型
  8. android 提高性能点
  9. 【CSS】背景遮罩层各种情况下,CSS样式
  10. 深度对话之小舟与他的无限世界