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;
}

poj 1821 Fence(单调队列优化DP)的更多相关文章

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

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

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

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

  3. $Poj1821\ Fence\ $单调队列优化$DP$

    Poj   Acwing Description 有N块木板等待被M个工匠粉刷,每块木板至多被刷一次.第i个工匠要么不粉刷,要么粉刷包含木块Si的,长度不超过Li的连续的一段木板,每粉刷一块可以得到P ...

  4. Dividing the Path POJ - 2373(单调队列优化dp)

    给出一个n长度的区间,然后有一些小区间只能被喷水一次,其他区间可以喷水多次,然后问你要把这个区间覆盖起来最小需要多少喷头,喷头的半径是[a, b]. 对于每个只能覆盖一次的区间,我们可以把他中间的部分 ...

  5. poj1821 Fence(单调队列优化dp)

    地址 一排N个木板,M个工匠站在不同位置$S_i$,每个人可以粉刷覆盖他位置的.最长长度为$L_i$木板段,每刷一个有$P_i$报酬.同一木板只刷一次.求最大报酬. 根据每个人的位置dp,设$f[i] ...

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

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

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

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

  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 ...

  10. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

随机推荐

  1. 【bzoj2989】数列 KD-tree+旋转坐标系

    题目描述 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Mo ...

  2. [BZOJ3378] [Usaco2004 Open]MooFest 狂欢节(树状数组)

    传送门 开2个树状数组 一个存的是下标,一个存的是数量 细节...看标称吧,懒得说了,好气啊 #include <cstdio> #include <iostream> #in ...

  3. testng自定义html报告,根据freemaker生成

    [转] https://testerhome.com/topics/3487 [参考]https://www.cnblogs.com/cheese320/p/8890929.html  做了些修改,换 ...

  4. Mysql字符集与校对规则

    字符集是一套字符和编码的集合,校对规则是用于比较字符集的一套规则. 所以字符集有两部分组成字符集合和对应的编码集合.比如说,现在有这几个字符:A B a b, 假设它们对应的编码分别是00, 01, ...

  5. 云计算与 OpenStack

    “云计算” 算是近年来最热的词了.现在 IT 行业见面不说这三个字您都不好意思跟人家打招呼. 对于云计算,学术界有各种定义,大家有兴趣可以百度一下. CloudMan 这里主要想从技术的角度谈谈对云计 ...

  6. 在App_Data中创建数据库获取连接串简便方法!

    原文发布时间为:2008-07-25 -- 来源于本人的百度文章 [由搬家工具导入] 1、在App_Data右击添加一个SQL数据库2、双击该数据库,在左边添加表,并显示表数据进行添加数据3、把刚刚创 ...

  7. JavaScript 的时间消耗--摘抄

    JavaScript 的时间消耗 2017-12-24 dwqs 前端那些事儿 随着我们的网站越来越依赖 JavaScript, 我们有时会(无意)用一些不易追踪的方式来传输一些(耗时的)东西. 在这 ...

  8. CSV文件导出2

    public void exportCSVFile( HttpServletResponse response, ResultSet rs,String fileName,String headers ...

  9. Unable to locate Attribute with the the given name [] on this ManagedType

    最近在写Springboot+hibernate的项目,遇到这个问题 好坑,查了半天没发现我哪里配置错了,后来发现实体类声明字段大小写敏感,把声明字段改成小写就行了

  10. Elasticsearch shield权限管理详解

    Elasticsearch shield权限管理详解 学习了:https://blog.csdn.net/napoay/article/details/52201558 现在(20180424)改名为 ...