题意: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. Header add Access-Control-Allow-Origin: *

    允许所有域名跨域 Header add Access-Control-Allow-Origin: *

  2. [Training Video - 3] [Groovy in Detail] Non-static and Static variables, objects and object referances

    log.info "starting" // we use class to create objects of a class Planet p1 = new Planet() ...

  3. Mybatis:传入参数方式以及#{}与${}的区别

    一.在MyBatis的select.insert.update.delete这些元素中都提到了parameterType这个属性.MyBatis现在可以使用的parameterType有基本数据类型和 ...

  4. 基于保守性和规则性的预测方法SIFT和PolyPhen

    有什么特征可以帮助我们来区分导致功能和表型变化的变异和其他变异,然后我们如何综合特征来做出一个预测模型? 表型或功能的改变(phenotypical/functional effect)a,个体表型上 ...

  5. xfce4快捷键设置

    xfce4的"Keyboard"可以方便的设置启动应用程序的快捷键. 例如,添加xfce4-terminal和emacs的启动快捷键 Alt+F3打开"Applicati ...

  6. 编写高质量代码改善C#程序的157个建议——建议145:避免过长的方法和过长的类

    建议145:避免过长的方法和过长的类 如果违反“一个方法只做一件事”及类型的“单一职责原则”,往往会产生过长的方法和过长的类. 如果方法过长,意味着可以站在更高的层次上重构出若干更小的方法.以行数作为 ...

  7. Ubuntu下安装配置java及环境变量

    这里的办法不是在线安装,因为需要更新源(你懂的,费时费事~),so这里介绍在Ubuntu上手动下载安装配置Java环境变量 *系统:Ubuntu 16.4 1.下载jdk,直接用系统的Firefox浏 ...

  8. 淘宝IP地址库

    淘宝官方ip地址库 http://ip.taobao.com/ 接口说明 1. 请求接口(GET): http://ip.taobao.com/service/getIpInfo.php?ip=[ip ...

  9. MongoDB默认配置

    mongodb使用了yaml格式定义的配置文件(http://www.yaml.org/) 默认为: # mongod.conf #where to log logpath=/var/log/mong ...

  10. Linq实战 之 DataSet操作详解

    Linq实战 之 DataSet操作详解  一:linq to Ado.Net 1. linq为什么要扩展ado.net,原因在于给既有代码增加福利.FCL中在ado.net上扩展了一些方法. 简单一 ...