题意:n个墙壁m个粉刷匠,每个墙壁至多能被刷一次,每个粉刷匠要么不刷,要么就粉刷包含第Si块的长度不超过Li的连续墙壁(中间可不刷),每一块被刷的墙壁都可获得Pi的利润,求最大利润

避免重复粉刷:

首先对Si排序并定义\(f[i][j]\):前i个木匠处理到第j块木板时的最大利润

此时[j+1,n]保证没被处理以满足无后效性

保证情况一的合法

\(f[i][j]=f[i-1][j]\)

保证情况二的Si必须被粉刷

定义处理的区间为[k+1,j]

则\(f[i][j]=max_kf[i-1][k]+P_i*(j-k)\)

此时要求Si必须在[k+1,j]内部,则对k加以限定:\(k+1≤S_i≤j\)

连续长度的表示:\(j-k≤L_i\)

中间可空出部分的表示\(f[i][j]=f[i][j-1]\)

由此可总结转移方程的三部分

前两部分为 \(f[i][j]=max(f[i-1][j],f[i][j-1])\)

最后一部分为\(f[i][j]=max_{j-L_i≤k≤S_i-1}f[i-1][k]+P_i*(j-k),S_i≤j\)

对于第三部分可改写方程为\(f[i][j]=max_{j-L_i≤k≤S_i-1}(f[i-1][k]-k*P_i)+j*P_i,S_i≤j\)以满足单调队列优化

单调队列在\(i\)的内循环当中可认为\(i\)是常数,也就是说每一层\(i\)都需要设立一个只与\(k\)有关的单调队列\(que\),但在实际中只使用一个

\(que\)每一次的初始化范围由最小的\(j\)决定

由\(S_i≤j\)和\(j-L_i≤k≤S_i-1\)

得\(S_i-L_i≤k_{init}≤S_i-1\)

此时\(j=1\)则得到所有有效的状态\(k\)

更新过程保证头部\(val\)最优,\(k\)单调递增(因为后者的更新顺序是从左往右)

注意单调更新时只对头部更新,因为单调范围右边界总是\(S_i-1\)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iter(i,j) for(int i=0;i<(j).size();i++)
#define print(a) printf("%lld",(ll)a)
#define println(a) printf("%lld\n",(ll)a)
#define printbk(a) printf("%lld ",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int MAXN = 2e4+11;
const int oo = 0x3f3f3f3f;
typedef long long ll;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct XJB{
int l,p,s;
bool operator < (const XJB &r) const{
return s<r.s;
}
}a[MAXN];
int n,m;
int f[233][MAXN];
inline int cal(int i,int k){
return f[i-1][k]-a[i].p*k;
}
int main(){
while(cin>>n>>m){
rep(i,1,m){
a[i].l=read();
a[i].p=read();
a[i].s=read();
}
sort(a+1,a+1+m);
memset(f,0,sizeof f);
deque<int> que;
rep(i,1,m){
while(!que.empty()) que.pop_back();
rep(k,max(0,a[i].s-a[i].l),a[i].s-1){ //j-Li<=k<=Si-1,j>=Si
while(!que.empty()&&cal(i,k)>=cal(i,que.back())) que.pop_back();
que.push_back(k);
}
rep(j,1,n){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(j>=a[i].s){
while(!que.empty()&&que.front()<j-a[i].l) que.pop_front();
if(!que.empty()) f[i][j]=max(f[i][j],cal(i,que.front())+a[i].p*j);
}
}
}
println(f[m][n]);
}
return 0;
}

POJ - 1821 单调队列优化DP + 部分笔记的更多相关文章

  1. 【笔记篇】单调队列优化dp学习笔记&&luogu2569_bzoj1855股票交♂易

    DP颂 DP之神 圣洁美丽 算法光芒照大地 我们怀着 崇高敬意 跪倒在DP神殿里 你的复杂 能让蒟蒻 试图入门却放弃 在你光辉 照耀下面 AC真心不容易 dp大概是最经久不衰 亘古不化的算法了吧. 而 ...

  2. POJ 2373 单调队列优化DP

    题意: 思路: f[i] = min(f[j]) + 1; 2 * a <= i - j <= 2 *b: i表示当前在第i个点.f[i]表示当前最少的线段个数 先是N^2的朴素DP(果断 ...

  3. poj 1821 Fence 单调队列优化dp

    /* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...

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

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

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

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

  6. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  7. 单调队列优化DP——习题收集

    前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...

  8. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  9. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

随机推荐

  1. JavaScript面向对象编程小游戏---贪吃蛇

    1 面向对象编程思想在程序项目中有着非常明显的优势: 1- 1 代码可读性高.由于继承的存在,即使改变需求,那么维护也只是在局部模块 1- 2 维护非常方便并且成本较低. ​ 2 这个demo是采用了 ...

  2. HDU 6005 Pandaland (Dijkstra)

    题意:给定一个图,找出一个最小环. 析:暴力枚举每一条,然后把边设置为最大值,以后就不用改回来了,然后跑一遍最短路,跑 n 次就好. 代码如下: #pragma comment(linker, &qu ...

  3. 用jvm指令分析String 常量池

    其他博友的不同理解方式:  http://hi.baidu.com/boywell/item/d5ee5b0cc0af55c875cd3cfd 我们先来看一个类 public class javaPT ...

  4. 获取host信息

    QT如果要进行网络编程首先需要在.pro”中添加如下代码: QT += network 在头文件中包含相关头文件: #include <QHostInfo> #include <QN ...

  5. poj—1753 (DFS+枚举)

                                                                                                        ...

  6. logback 配置详解——logger、root

    目录 1.根节点包含的属性 2.根节点的子节点 2.1.设置上下文名称: 2.2.设置loger.root 正文 回到顶部 1.根节点<configuration>包含的属性 scan: ...

  7. Linq集合操作之Intersect,Except,Union源码分析

    Linq集合操作之Intersect,Except,Union源码分析 linq的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...

  8. IIS应用程序池自动回收作业

    vb: appPoolName = WScript.Arguments() Set oWebAdmin = GetObject("winmgmts:root\WebAdministratio ...

  9. Replication--修改复制代理配置来查看代理运行情况

    1>在复制监视器中选中订阅右键 2>选择代理配置文件 3>将代理配置文件设置为”详细历史记录代理配置文件“,确定以保存 4>重启代理 5>代理运行一段时间后,重启代理 6 ...

  10. Spring学习(一)——环境准备

            以前做的项目都是用.net开发的,以后准备迁移到java平台上,近期正好有个新项目要上马,所以调研下java相关技术.Spring作为java平台下的一个全栈框架, 其简洁优雅的设计和 ...